From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3042 invoked by alias); 17 Jun 2009 16:23:52 -0000 Received: (qmail 3030 invoked by uid 22791); 17 Jun 2009 16:23:51 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from NaN.false.org (HELO nan.false.org) (208.75.86.248) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 17 Jun 2009 16:23:45 +0000 Received: from nan.false.org (localhost [127.0.0.1]) by nan.false.org (Postfix) with ESMTP id 9FE1B7C09B; Wed, 17 Jun 2009 16:23:39 +0000 (GMT) Received: from caradoc.them.org (209.195.188.212.nauticom.net [209.195.188.212]) by nan.false.org (Postfix) with ESMTP id 3123E7C09A; Wed, 17 Jun 2009 16:23:39 +0000 (GMT) Received: from drow by caradoc.them.org with local (Exim 4.69) (envelope-from ) id 1MGxvF-0002WP-WF; Wed, 17 Jun 2009 12:23:38 -0400 Date: Wed, 17 Jun 2009 18:10:00 -0000 From: Daniel Jacobowitz To: Christophe LYON Cc: binutils@sourceware.org, Nick Clifton , Phil Blundell Subject: Re: linker crash in arm stub generation Message-ID: <20090617162337.GA9315@caradoc.them.org> Mail-Followup-To: Christophe LYON , binutils@sourceware.org, Nick Clifton , Phil Blundell References: <1244740179.21585.119.camel@mill.internal.reciva.com> <4A324BAC.7090702@redhat.com> <4A3255D9.9030906@st.com> <20090612140642.GA31950@caradoc.them.org> <4A32626C.8090407@st.com> <4A3658C4.3000800@st.com> <20090615175935.GA22200@caradoc.them.org> <4A390CF5.3000505@st.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4A390CF5.3000505@st.com> User-Agent: Mutt/1.5.17 (2008-05-11) X-IsSubscribed: yes Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2009-06/txt/msg00288.txt.bz2 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