[patch] init_array/fini_array support

John Bowler jbowler at acm.org
Wed Feb 1 18:51:54 UTC 2006


The isn't directly connected with the weak/strong issues, but it
is related to how function pointers get handled and, if I understand
the new init/fini stuff it may be relevant.

I think the reason this stuff works but it is extremly obscure...

From: Joakim Tjernlund [mailto:joakim.tjernlund at transmode.se]
>>JBowler:
>> 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?

As you say, wrong.  st_shndx == SHN_UNDEF causes the symbol to
be skipped when resolving a reference with ELF_RTYPE_CLASS_PLT.

The cases where this arises on ARM are:

1) When handling the PLT itself and trying to find the value to
   put into the GOT (the GOT entry contains a simple function
   pointer).
2) When the type of the relocation is R_ARM_JUMP_SLOT - I believe
   that means the thing being relocated is a function pointer.

>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

Well, it's pretty clear what is required - a PLT entry should never
resolve a relocation within a PLT which is looking for a function
pointer.  The obscure part is that st_shndx is set to SHN_UNDEF for
a PLT entry.

Here's the relevant section of the PPC spec:

"If an executable file contains a reference to a function defined
in one of its associated shared objects, the symbol table section
for the file will contain an entry for that symbol. The st_shndx
member of that symbol table entry contains SHN_UNDEF. This
informs the dynamic linker that the symbol definition for that
function is not contained in the executable file itself. If that
symbol has been allocated a procedure linkage table entry in the
executable file, and the st_value member for that symbol table
entry is nonzero, the value is the virtual address of the first
instruction of that procedure linkage table entry. Otherwise,
the st_value member contains zero."

In other words, st_value!=0 points to the PLT, not to the actual
function.  So if it is used to resolve a symbol everything
will work, but the code will end up unnecessarily executing the 
PLT entry before branching to the real function.

You quoted the other reference in that document before:

"If the st_shndx member is SHN_UNDEF and the symbol is of type
STT_FUNC and the st_value member is not zero, the dynamic
linker recognizes this entry as special and uses the st_value
member as the symbol's address."

But we need to read the preceding paragraphs to see what this
is all about - it is an attempt to ensure that something of the
form:

if (pointer_to_function == strcmp)

does actually work as expected.  Therefore it resolves all
function pointers except those used by the PLT (the GOT
entry IIRC) to point into the PLT.  From the PPC spec
just before the quote above:

"To allow comparisons of function addresses to work as
expected, if an executable file references a function defined
in a shared object, the link editor will place the address
of the procedure linkage table entry for that function in
its associated symbol table entry."

Duh.  Wrong.  That only works within a single DLL - it means
each DLL has a different address for the same (external)
symbol.  Of course the failure case is vanishingly rare -
two DLLs exchanging and comparing pointers to the same
external function.

I think this stuff was broken in ELF throughout the '90s
(the PPC document is dated 1995) and may still be broken
now.  However I think it works because the cases in question
are never encountered...  The only one which actually
fails (as opposed to unnecessarily executing PLT code) is
the obscure function pointer comparison.

John Bowler <jbowler at acm.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: winmail.dat
Type: application/ms-tnef
Size: 3772 bytes
Desc: not available
Url : http://lists.busybox.net/pipermail/uclibc/attachments/20060201/88a927dd/attachment.bin 


More information about the uClibc mailing list