[patch] init_array/fini_array support

Joakim Tjernlund joakim.tjernlund at transmode.se
Wed Feb 1 09:36:02 UTC 2006


> -----Original Message-----
> From: John Bowler [mailto:jbowler at acm.org] 
> Sent: 01 February 2006 08:54
> To: Joakim Tjernlund; 'Joseph S. Myers'; 'Peter S. Mazinger'
> Cc: uclibc at uclibc.org
> Subject: RE: [patch] init_array/fini_array support
> 
> From: Joakim Tjernlund [mailto:joakim.tjernlund at transmode.se]
> >Weak symbols are handled in ld.so, but how they are handled 
> changed(between .26 and .27 I think)
> >Look in elfinterp.c for:
> >if (unlikely(!symbol_addr && 
> ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
> 
> Ok, I started out on the thumb stuff in .27 and some of the 
> things I had
> to do may be a result of that...
> 
> Without my patch .28 is as you say - _dl_find_hash returns the first
> definition it finds, regardless of whether it is weak or not:
> 
> >earlier ld.so would try to find a strong sym before 
> resorting to a weak sym, now ld.so will
> >use the first sym it finds, does not matter if its weak or 
> strong. This
> >will break a few apps/libs(linuxthreads was one). Now you 
> will have to use something like this for
> >weak syms:
> >extern weak fun();
> >if (fun)
> >    fun();
> 
> Umm... well, if I have one module which has a weak definition 
> for something and
> another which has a strong one I understood that the 
> intention was that the
> strong be used.  That no longer happens - even with the above check.

That behaviour no longer works as you have seen. What you must do is:
extern weak my_real_fun(); // the actual function can be a strong or
weak function.
if (my_fun) // test if my_fun can be found in any lib or app.
    my_fun(); //yes, call that fun.
else // my_real_fun isn't present
    my_local_fun() // call a my own local version which must have a
diffrent name.

I know this isn't any fun and people has had problems with it.
Google with LD_DYNAMIC_WEAK to find out more

In http://sourceware.org/ml/binutils/2003-02/msg00014.html
you can read:
"glibc treats weak and non-weak equally when doing lookup
(unless LD_DYNAMIC_WEAK is used), since 2002-12-19 in NPTL ld.so builds
and since 2003-01-07 for all the rest.

	Jakub"

> 
> Indeed the requirement for the above stuff is a consequence 
> of not erroring out if
> no definition is found for a weak *reference*.  That's a 
> different issue isn't it?
> dl-hash.c is handling weak definitions, elfinterp.c is 
> handling weak references
> (where a 'reference' is identified by value==0, (+ value==1 
> for thumb) and a
> 'definition' is value != 0/1
> 
> Still, if glibc does it (use the first definition found even 
> if weak) it must be right...

In http://sourceware.org/ml/binutils/2003-02/msg00014.html
you can read:
"glibc treats weak and non-weak equally when doing lookup
(unless LD_DYNAMIC_WEAK is used), since 2002-12-19 in NPTL ld.so builds
and since 2003-01-07 for all the rest.

	Jakub"

> 
> >from what you have told me I think the only difference for 
> thumb is that thumb transforms 
> >the STT_ATM_TFUNC into value=1 instead. You will have to do 
> something in dl_find_hash
> >to resolve this correctly.
> 
> That's a different issue - in the case in point a *reference* 
> to an undefined
> symbol was used to resolve another reference.  It can be 
> fixed in the way you
> suggest - checking for value == 0 || value == 1 && type == 
> ARM_STT_TFUNC
> 
> I'm still mystified by this piece of code in dl-hash.c 0.9.28:
> if (type_class & (sym->st_shndx == SHN_UNDEF))
>    [skip this symbol]
> 
> Of course I know what it *does* but I'm not sure I understand why you
> skip SHN_UNDEF symbols if the caller passes in ELF_RTYPE_CLASS_PLT.

yeah, this is a bit strange.
  if (sym->st_shndx == SHN_UNDEF)
      [skip this symbol]
would be more logical. I destilled this from glibc and and tried to do
the
as they did, can't be 100% sure I got it right. The current dl_find_hash
has
been in use for some time now and don't know of any problems(other than
yours)
I got most of this from libc/elf/do-lookup.h in glibc.


> 
> The actual comments in the header files say this this flag is meant
> to mean that _dl_find_hash should not return a PLT entry - 
> and the comments
> say this in two separate places - yet the code in 
> _dl_find_hash (above)
> is extremely obscure.  The implication is that st_shndx == SHN_UNDEF
> and value != 0 is used for definitions of PLT entries, have I got that
> right?

No, i think its:
  st_shndx == SHN_UNDEF is NOT used for PLTs.
  A non PLT entry will be used if st_value is != 0, regardless of
st_shndx value.

I still think this strange code is for function ptrs, as specifed in
http://refspecs.freestandards.org/elf/elfspec_ppc.pdf

  Jocke



More information about the uClibc mailing list