Bug 17505 - arm: bad static label resolution from different modes
Summary: arm: bad static label resolution from different modes
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-23 12:28 UTC by Christian Bruel
Modified: 2015-09-21 11:10 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
test to reproduce (220 bytes, text/plain)
2014-10-23 12:28 UTC, Christian Bruel
Details
tentative patch (651 bytes, patch)
2014-10-30 14:54 UTC, Christian Bruel
Details | Diff
New test (492 bytes, text/plain)
2014-10-30 15:00 UTC, Christian Bruel
Details
the c input (152 bytes, text/x-csrc)
2014-10-30 15:02 UTC, Christian Bruel
Details
complete runable assembly (498 bytes, text/plain)
2014-11-05 16:54 UTC, Christian Bruel
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Bruel 2014-10-23 12:28:16 UTC
Created attachment 7843 [details]
test to reproduce

While working on the attribute_target GCC attribute, I find myself calling a static THUMB function while in ARM mode, or vice versa.

(this works fine when functions are .global)

Using the attached .s example, with 
foo:

	.thumb_func
	.type	bar, %function


 the relocations are in the object

00000000 <main>:
 00000000 <main>:
   0:	ebfffffe 	bl	0 <main>
			0: R_ARM_CALL	foo
   4:	ebfffffe 	bl	0 <main>
			4: R_ARM_CALL	bar

is resolved in the final binary as:

Disassembly of section .text:

00008018 <main>:
    8018:	eb000085 	bl	8234 <bar>
    801c:	fa000084 	blx	8234 <bar>

instead of bl <foo>

What is surprising is that the linker correctly patches the BL/BLX instructions, itś just the address that is wrong. I´m wondering if this can be fixed in the linker machinery to handle interwork or have the assembly emit a R_ARM_THM_CALL reloc 

assembled/linked with :

arm-none-eabi-gcc  1.s -o 1.u
Comment 1 Christian Bruel 2014-10-30 14:52:22 UTC
Encoding a BFD_RELOC_ARM_PCREL_BLX instead of a BFD_RELOC_ARM_PCREL_CALL for static calls between arm to thumb fixed the problem.
Comment 2 Christian Bruel 2014-10-30 14:54:24 UTC
Created attachment 7866 [details]
tentative patch
Comment 3 Christian Bruel 2014-10-30 15:00:44 UTC
Created attachment 7867 [details]
New test

compiles with arm-none-eabi-gcc -march=armv7-a 1.s 

previous objdump was :

    801c:	eb00008a 	bl	824c <foo>
    8020:	e1a03000 	mov	r3, r0
    8024:	fa00008c 	blx	825c <rab+0x4>
    8028:	e0833000 	add	r3, r3, r0
    802c:	eb000089 	bl	8258 <rab>

now :

    801c:	eb00008a 	bl	824c <foo>
    8020:	e1a03000 	mov	r3, r0
    8024:	fa00008a 	blx	8254 <bar>
    8028:	e0833000 	add	r3, r3, r0
    802c:	eb000089 	bl	8258 <rab>
Comment 4 Christian Bruel 2014-10-30 15:02:12 UTC
Created attachment 7868 [details]
the c input

causing the situation, for reference (need attribute target support)
Comment 5 Richard Earnshaw 2014-11-05 11:48:48 UTC
(In reply to Christian Bruel from comment #1)
> Encoding a BFD_RELOC_ARM_PCREL_BLX instead of a BFD_RELOC_ARM_PCREL_CALL for
> static calls between arm to thumb fixed the problem.

That sounds wrong.

Which architecture revision are you targeting?
Comment 6 Christian Bruel 2014-11-05 11:54:50 UTC
(In reply to Richard Earnshaw from comment #5)
> (In reply to Christian Bruel from comment #1)
> > Encoding a BFD_RELOC_ARM_PCREL_BLX instead of a BFD_RELOC_ARM_PCREL_CALL for
> > static calls between arm to thumb fixed the problem.
> 
> That sounds wrong.

it is indeed, fixed locally but many other regressions. 

> 
> Which architecture revision are you targeting?

v7 and v5
Comment 7 Richard Earnshaw 2014-11-05 15:49:14 UTC
> What is surprising is that the linker correctly patches the BL/BLX instructions, itś just the address that is wrong. I´m wondering if this can be fixed in the linker machinery to handle interwork or have the assembly emit a R_ARM_THM_CALL reloc 

I think you're being confused by the disassembler.  The two symbols are at the same address (there's no code in between the two); so the disassembler just picks one of them to print out.

I still don't see anything wrong with what's being generated by the assembler/linker.
Comment 8 Christian Bruel 2014-11-05 16:52:48 UTC
sorry, the first test was only illustrative, but not completed. the fact that the addresses are the same is just because I reduced the code. 

Here is the complete attachment, here the code is : 

00008240 <foo>:
    8240:	e30b3178 	movw	r3, #45432	; 0xb178
    8244:	e3e0207e 	mvn	r2, #126	; 0x7e
    8248:	e3403001 	movt	r3, #1
    824c:	e5933000 	ldr	r3, [r3]
    8250:	e5c32000 	strb	r2, [r3]
    8254:	e12fff1e 	bx	lr

00008258 <bar>:
    8258:	4770      	bx	lr
    825a:	bf00      	nop

and main calls : 

00008018 <main>:
    8018:	e92d4010 	push	{r4, lr}
    801c:	fa000093 	blx	8270 <atexit+0x14>
    8020:	eb000086 	bl	8240 <foo>
    8024:	e3a00000 	mov	r0, #0
    8028:	e8bd8010 	pop	{r4, pc}

so

 bl	bar

is in the .o

   4:	eb000004 	bl	30 <bar+0x18>
			4: R_ARM_CALL	bar

instead of just 	bl	30 <0x18>

looks like a wrong addend to the start of the section.

to reproduce:

arm-none-eabi-gcc -march=armv7-a 2.s -c -o 1.o
arm-none-eabi-objdump -dr 1.o | grep bar

arm-none-eabi-gcc -march=armv7-a 2.s -o 1.u
arm-none-eabi-objdump -dr 1.u
Comment 9 Christian Bruel 2014-11-05 16:54:46 UTC
Created attachment 7903 [details]
complete runable assembly
Comment 10 Christian Bruel 2014-11-06 08:13:07 UTC
in the .o dump bar is at

   .text
00000000 <foo>:
   ...
00000018 <bar>:

but the call to bar resolves:

  4:	eb000004 	bl	30 <bar+0x18>
			4: R_ARM_CALL	bar


why the +0x18 addend ? 

it shoud be either bl <foo+0x18>

or just (prefered) bl <bar>
Comment 11 Christian Bruel 2015-09-21 11:10:35 UTC
gcc 6.0.0 fixed to resolve interwork static thumb2 calls, so the linker fixup is not needed anymore.