Thumb->ARM call and thumb-interwork problem on 4.7

Asked by jdobry

Hello,

I have problem to call ARM coded assembler function from C Thumb code. It works fine on 4.6 2012q4
But it fails on 4.7 2013q1 and also in new 4.7 2013q2

Problem is that linker not change BL instruction to BLX when source is in Thumb code and target in ARM code. (thumb-interwork)

For explicit declaration for "thumb" function we have ".thumb_func" keyword. But we don't have keyword for explicit ARM function in assembler.
Is it bug in compiler or I am use it badly?
In case bug, do you have any work around? Except change assembler into "thumb"?

Jiri

Here is ASM code (file test.S):
===========================
  .syntax unified
  .text
  .code 32

  .global test
  .func test
test:
   nop
   bx lr
.endfunc

Here is C code (file c.c):
============================
void test (void);
int test2 (void)
{
  test();
}

Script for compilation
============================
arm-none-eabi-gcc -c -mcpu=cortex-r4 -mthumb-interwork -Wa,-gdwarf2 -x assembler-with-cpp test.S
arm-none-eabi-gcc -c -mcpu=cortex-r4 -mthumb -mthumb-interwork -Wa,-gdwarf2 c.c
arm-none-eabi-gcc -o test.elf -mcpu=cortex-r4 -mthumb -mthumb-interwork -g -nostartfiles test.o c.o
arm-none-eabi-objdump.exe -d test.elf > test.dump

And here is broken dissembled result with my note:
===========================
Disassembly of section .text:

00008000 <test>:
    8000: e320f000 nop {0}
    8004: e12fff1e bx lr

00008008 <test2>:
    8008: b580 push {r7, lr}
    800a: af00 add r7, sp, #0
    800c: f7ff fff8 bl 8000 <test> ; !!!!!!!!!!!! <- here must be BLX not BL
    8010: 4618 mov r0, r3
    8012: bd80 pop {r7, pc}

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Joey Ye
Solved:
Last query:
Last reply:
Revision history for this message
jdobry (jdobry) said :
#1

I also try to force Thumb->ARM call by function declaration

void __attribute__((interfacearm)) test (void);

Nothing changed. :-(

Revision history for this message
Terry Guo (terry.guo) said :
#2

Thanks for reporting. I can reproduce this issue and am working on it now.

Revision history for this message
Joey Ye (jinyun-ye) said :
#3

I might misread the command line. But it seems the .s shouldn't be built
with -mthumb
On Jun 28, 2013 9:01 PM, "Terry Guo" <email address hidden>
wrote:

> Question #231518 on GCC ARM Embedded changed:
> https://answers.launchpad.net/gcc-arm-embedded/+question/231518
>
> Terry Guo posted a new comment:
> Thanks for reporting. I can reproduce this issue and am working on it
> now.
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
jdobry (jdobry) said :
#4

Hello Joey,

Missed "-mthumb" is correct. I just remove all unneeded parameters and code is for simple demonstration of problem.
It is many reasons why use 32 bit ARM assembler in Thumb C code:
- 3rd party code, where is not possible made changes by licence reasons.
- Code created by chip vendor code generator. It is possible change manually, but it "freeze" code on current status and it isn't possible to regenerate it with changed settings.
- Share some code with interrupt (interrupt always start in ARM mode)
- Optimize some time critical code. ARM instruction allow for example make combined conditions like tree "<0", "==0", ">0" just on 2 instructions, "IT" thumb conditions not allow this. (I know that "IT" instruction can have zero ticks on some situations)

But it is not significant, why somebody need mix ARM and Thumb code. Problem is, that this possibility is documented. I was work, bud not working with new version of compiler.

Here is improved demonstration of problem: http://ge.tt/3riqkVk/v/0?c

Jiri

Revision history for this message
Best Joey Ye (jinyun-ye) said :
#5

Jiri,

After further study, it turns out to be the incorrect assembly code.

You are missing an important assembly directive:
.type test, %function

After changing your small test to:
  .syntax unified
  .text
  .code 32

  .global test
  .type test, %function
  .func test
test:
   nop
   bx lr
.endfunc

and similar changes in thumb_test.zip, they both passes with expected result. Without this directive, assembler is getting lost to know a function symbol.

I assume it is a misunderstanding of directive .func/.endfunc. Please refer to http://sourceware.org/binutils/docs-2.22/as/Func.html#Func for their usage, which isn't function symbol definition as it appears to be.

Thanks,
Joey

Revision history for this message
jdobry (jdobry) said :
#6

Joey,

Many thanks for information.

Jiri

Revision history for this message
jdobry (jdobry) said :
#7

Thanks Joey Ye, that solved my question.