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


On Wed, Jun 17, 2009 at 05:34:13PM +0200, Christophe LYON wrote:
>> 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)

That's right.  Except that a constant pool should never have dynamic
relocations; it's read-only.  But for instance an initialized writable
data structure could have such a relocation.

> > 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)?

It doesn't matter.  Easy because there are appropriate dynamic
relocations.  There aren't dynamic relocations for, for instance,
movw / movt.

> > 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?

No, PLTs are generated and used - but only for lazy resolution.  If
you have a global variable "void (*funp) (void) = function" you can't
lazily resolve "function" because the value of funp is observable by
the program.  The address of a called function is not observable.

> 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.

This is an SVR4 dynamic linking environment we're talking about.
There's only ever one executable in the address space.  In a flat,
non-virtual address space, like uClinux, you don't do PIC this same
way.  There needs to be a separate copy of the entire writable
data segment, not just the GOT.

>> 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?

Several reasons.  The appropriate dynamic relocations are not
defined.  It's slow.  And it requires making the read-only text
segment writable to patch it, which is bad for both performance and
security.

> 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.

A branch to a preemptible symbol is always supposed to go to the PLT
entry, and we know the mode of the PLT entry - or sometimes it's
available in both modes depending on the mode of the call site ("bx
pc" Thumb stub in front of the PLT).  So you get to pick which PLT
entry you're going to reach from the long branch stub.  I'd imagine
it's generally profitable to use the ARM mode PLT entry point.

-- 
Daniel Jacobowitz
CodeSourcery


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