public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Dave Martin <dave.martin@linaro.org>
To: Richard Earnshaw <rearnsha@arm.com>
Cc: Richard Sandiford <richard.sandiford@linaro.org>,
	binutils@sourceware.org, 	patches@linaro.org
Subject: Re: Fix assembly of Thumb pcrel LDRs against global symbols
Date: Wed, 02 Mar 2011 16:37:00 -0000	[thread overview]
Message-ID: <AANLkTi=Dw7KAkmk9WuQHtN6CfrzRXUromRxmPYXbpkL3@mail.gmail.com> (raw)
In-Reply-To: <1299079089.24968.14.camel@e102346-lin.cambridge.arm.com>

On Wed, Mar 2, 2011 at 3:18 PM, Richard Earnshaw <rearnsha@arm.com> wrote:
>
> On Mon, 2011-02-28 at 12:59 +0000, Richard Sandiford wrote:
>> The PC-relative LDR instructions have no associated relocation,
>> so even LDRs for global symbols should be resolved by the assembler.
>> We currently handle this correctly for single-register ARM loads,
>> but we're missing the associated relocation types for LDRD and Thumb.
>> This leads to errors like:
>
> I'm not sure I agree with this.  If I write
>
> .global foo
>
> ...
>        ldr r0, foo
>
> ...
>
> foo:
>        ...
>
> but then at link/load time pre-empt foo with some other definition, that
> will silently leave me with the wrong answer.
>
> It's clearly OK to do this if foo is protected or private, but not
> otherwise.
>
> The existing error message is not very informative as to what the
> problem is, but I'm not sure I agree with your solution...
>
> R.

That's a reasonable argument, but similarly to the ADR case, such code
referencing global symbols is already allowed through for ARM _with no
relocation emitted_  - the Thumb treatment is inconsistent and causes
existing code which builds for ARM (but where symbol preemption may
silently fail to work).  This raises non-trivial questions about which
behaviour should be considered correct.

Unless there are some tricks I haven't thought of, it seems that ADR
and PC-relative LDR and friends simply can't be generally preemptible,
period -- because the relocation ranges these instructions support
just aren't large enough to guarantee that a relocation on these
instructions can ever be resolved except in a trivial subset of cases.

Solving this inconsistency requires a conclusion regarding whether the
tools should trust the programmer to write correct code (i.e., fix up
pc-relative LDR and ADR in the assembler and emit no relocation) or
not (i.e., treat these instructions as an error when they reference
global symbols).

I would regard the latter option as incorrect, since it's quite
legitimate to use these instructions in this way in static
environments, and the assembler doesn't have knowledge of whether this
is what's intended.  There is also a possible middle way of allowing
the instructions but always emitting a relocation, which allows a tool
further down the line to check whether the preemption is needed and
throw an error if so.  Since the Linux kernel doesn't do symbol
preemption it can safely ignore these relocations with a tiny amount
of extra code in the module loader.

In general, we can't expect to prevent absolutely the programmer from
doing something that generates the wrong answer, such as writing
non-PIC code and the linking it into a PIC environment; though any
diagnostics which help avoid this happening by accident are still
useful.


To give the flipside to this, there is a case when the assembler knows
that preemption absolutely must be supported, and that is when a
symbol is declared weak.  So:

.type g, %function
g:	ldr	r0, d

	.weak d
d:	.long 0

$ arm-linux-gnueabi-as --version
GNU assembler (GNU Binutils for Ubuntu) 2.20.51.20100908
[...]
$ arm-linux-gnueabi-as -o tst.o tst.s && arm-linux-gnueabi-objdump -drt tst.o
tst.s: Assembler messages:
tst.s:2: Error: internal_relocation (type: OFFSET_IMM) not fixed up
$ arm-linux-gnueabi-as -mthumb -o tst.o tst.s &&
arm-linux-gnueabi-objdump -drt tst.o
tst.s: Assembler messages:
tst.s:2: Error: invalid offset, value too big (0xFFFFFFFFFFFFFFFC)

i.e., cryptic error messages aside, the assembler fails sensibly for
ARM and Thumb alike.  This is appropriate, because ".weak" declares
explicitly the need for preemptibility, and the assembler knows that
can't be guaranteed with these instruction forms.  ".globl" does not,
because where the symbol is not weak it's impossible for the assembler
to know what the programmer intends, and so throwing an error for such
cases seems too zealous from my point of view.

For comparison, changing ".weak" to ".globl" in the above example gives:
$ arm-linux-gnueabi-as -o tst.o tst.s && arm-linux-gnueabi-objdump -drt tst.o
[...]
00000004 g       .text	00000000 d
[...]
00000000 <f>:
   0:	e51f0004 	ldr	r0, [pc, #-4]	; 4 <d>
00000004 <d>:
   4:	00000000 	.word	0x00000000

$ arm-linux-gnueabi-as -mthumb -o tst.o tst.s &&
arm-linux-gnueabi-objdump -drt tst.o
tst.s: Assembler messages:
tst.s:2: Error: invalid offset, value too big (0xFFFFFFFFFFFFFFFC)

Notice that the ARM code refernce to d is not preemptible.

Cheers
---Dave

  parent reply	other threads:[~2011-03-02 16:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-28 12:59 Richard Sandiford
2011-03-01 11:26 ` Dave Martin
2011-03-01 13:50   ` Richard Sandiford
2011-03-02 15:18 ` Richard Earnshaw
2011-03-02 16:36   ` Richard Sandiford
2011-03-02 16:37   ` Dave Martin [this message]
2011-03-02 16:45     ` Richard Earnshaw
2011-03-02 17:04       ` Dave Martin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='AANLkTi=Dw7KAkmk9WuQHtN6CfrzRXUromRxmPYXbpkL3@mail.gmail.com' \
    --to=dave.martin@linaro.org \
    --cc=binutils@sourceware.org \
    --cc=patches@linaro.org \
    --cc=rearnsha@arm.com \
    --cc=richard.sandiford@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).