This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

Re: linker crash in arm stub generation


Hi Daniel,

Thank you for your answer, but I am afraid things are still not clear to me, despite reading your answer several times :-(

(part of the confusion probably comes from the fact that I deal with different architectures, too...)

I have started to look at this problem more closely, and I have one question: in elf32-arm.c:allocate_dynrelocs(), there is this comment:

  /* If this symbol is not defined in a regular file, and we are
     not generating a shared library, then set the symbol to this
     location in the .plt.  This is required to make function
     pointers compare as equal between the normal executable and
     the shared library.  */

Why is the behaviour different when generating a shared lib?

I thought I had understood the comment about function pointers comparison, but I am wondering now....

A PLT entry with a non-zero address is used as the canonical location of the function.
This "canonical" location is only used by the dynamic linker, when it patches the dyn relocs pointing to this symbol, right? (when the address of the function is stored in a constant pool for instance, or in GOT)

> This is only ever required in an executable, never
in a shared library.  If all accesses to the address are PIC - which
they must be, in a shared library - then they can be easily adjusted
to point to the function's address.
Easy because the dyn linker needs to patch the GOT only (ie one entry instead of several references)?

> And it's better to do that,
because calls through those pointers will go directly to the function
instead of to the PLT.
So you mean that in a shared lib, PLT are generated, but not executed because the dyn linker manages to make these indirect calls go directly to the function?

But then, how is symbol preemption handled? I mean, if a shared lib is actually shared, ie used by two different executables, and one of them preempts the function definition, but not the other, I think the calls need to go through the PLT so that different GOTs are used to reach different functions.

In an executable, this might not be the case.  For instance you might
have the address of the funtion in a constant pool in the text
segment.  If that happens, the linker must fix the address of the
function at static link time, even if the definition turns out to be
in a shared library.
Why couldn't this be performed at load time?

Such code is (or is supposed to be, anyway) rejected in shared
objects.


I thought your answer would help me solve my actual problem, but since it seems that I need better understanding, I will expose my actual question here:
If I am generating a shared lib, let's say that some ARM code references a THUMB function in a shared lib.
As the target is in a shared lib, we need to have a PLT generated.
But, we also need to know if we need to change modes, and if we need a long branch stub.


However, because of the comment I mentioned earlier, the destination is not recorded as being the PLT, so we don't know the actual distance, and the symbol type is not switched to ARM type.

This scenario is handled properly when generating an executable, but when generating a shared lib, the current generation is broken.

Christophe.

PS: I have noted that Phil Blundell has inadvertently committed a wrong patch for the issue being discussed (as part of another commit of his). I don't know if it should be cancelled separately or if it can't wait until I propose a full patch + testcase.


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