This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [patch] R_ARM_REL32 and Thumb functions.
On Thu, 2006-04-20 at 19:49, Daniel Jacobowitz wrote:
> On Thu, Apr 20, 2006 at 07:29:49PM +0100, Paul Brook wrote:
> > The attached patch makes the R_ARM_REL32 relocation set the low bit of the
> > value when the relocated symbol is a Thumb function, as required by the ARM
> > EABI.
> >
> > I don't know if the current behavior is considered a bug or a feature for
> > pre-EABI objects. For now I'm assuming bug, and making the change
> > unconditionally. I can preserver the old behavior if anything depends on it.
> >
> > A slight complication is that gas will try and fold relative expressions at
> > assembly time. This folding is done in generic code, so gets the value wrong.
> > e.g.
> >
> > .thumb_func
> > foo:
> > .word foo - .
> >
> > Will be folded to zero by gas/expr.c:expr. I've [ab]used md_optimize_expr to
> > prevent this happening.
> >
> > Initially I disabled the folding if either symbol was a Thumb function.
> > However this ends up breaking the explicit cfi directives in libgcc, so I've
> > only disabled the folding when the first symbol is a Thumb function.
>
> Wow, this is nasty!
>
> I can understand why Richard, and presumably the ABI, wants this to
> happen:
>
> ldr ip, 1f
> 2: add ip, pc, ip
> bx ip
> 1: .word foo - . - (2b - .)
>
> But I'd be mighty confused if, say, some code tried to copy itself from
> one location to another and expected "foo - ." to describe the number
> of bytes to be copied. And now "foo - ." and ". - foo" are assymetric.
It's only done if the symbol is a Thumb Function symbol (ie has type
STT_FUNC and addresses Thumb code). So if you want to treat your code
as data, add some other symbol at the same address with a different type
and use that for the data accesses. So
.type F_as_data, object
.type F_as_code, function
.thumb_func
F_as_code:
F_as_data:
...
.word F_as_code - .
.word F_as_data - .
Will cause the first .word entry to be a pc-relative code label, and the
second to be a pc-relative data label.
If you look at AAELF you'll see that the change here is to make
relocation processing consistent -- why should R_ARM_REL32 not set the T
bit when R_ARM_ABS32 does?
R.