[arm-gnu] possible bug with arm-thumb veneers
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[arm-gnu] possible bug with arm-thumb veneers



Hi,

I'm experiencing some problems with arm-thumb interworking with the GCC ARM 2009 Q3 EABI release, on win32.

The problem appears to be in generation of the xxx_from_arm veneers, when compiling and linking code for architecture arm4T. I've confirmed that this is a linker issue, as reverting the linker binary (ld.exe) to the 2008 Q3 release fixes the problem, (sorry I haven't tested the 2009 q1 version yet).

I'm linking with the following options

-Wl,-Map=./Debug_IwGxPolygonDisplay_vc6_gcc_arm/IwGxPolygonDisplay.map
-Wl,--gc-sections
-Wl,--as-needed
-mthumb-interwork
-pie
-Wl,--entry=s3e_start
-Wl,--no-enum-size-warning
-Wl,-Tlinker_script

the linker script I've confirmed isn't relevant, as removing the option "-Wl,-Tlinker_script" (so reverting to the default) still generates the same broken code.

The problem isn't consistent between applications that I link. When it goes wrong I get output like this:

   s3e_start
   $a
       0x4a000000:    e92d4038    8@-.    PUSH     {r3-r5,r14}
       0x4a000004:    e31d0004    ....    TST      r13,#4
       0x4a000008:    03a05000    .P..    MOVEQ    r5,#0
       0x4a00000c:    13a05001    .P..    MOVNE    r5,#1
       0x4a000010:    124dd004    ..M.    SUBNE    r13,r13,#4
0x4a000014: eb011fa6 .... BL __libc_init_array ; 0x4a047eb4
       0x4a000018:    eb00fab1    ....    BL       iwcrt_init  ; 0x4a03eae4
0x4a00001c: eb00000d .... BL __IwMain_from_arm ; 0x4a000058
       0x4a000020:    e1a04000    .@..    MOV      r4,r0
       0x4a000024:    e1a01000    ....    MOV      r1,r0
       0x4a000028:    e3a0000f    ....    MOV      r0,#0xf
       0x4a00002c:    eb0000a8    ....    BL       0x4a0002d4
       0x4a000030:    e1a00004    ....    MOV      r0,r4
       0x4a000034:    e3a01000    ....    MOV      r1,#0
0x4a000038: eb011d75 u... BL __call_exitprocs ; 0x4a047614
       0x4a00003c:    eb00f9c1    ....    BL       iwcrt_fini  ; 0x4a03e748
0x4a000040: eb011df4 .... BL __libc_fini_array ; 0x4a047818
       0x4a000044:    e3150001    ....    TST      r5,#1
       0x4a000048:    128dd004    ....    ADDNE    r13,r13,#4
       0x4a00004c:    e3a00000    ....    MOV      r0,#0
       0x4a000050:    e8bd4038    8@..    POP      {r3-r5,r14}
       0x4a000054:    e12fff1e    ../.    BX       r14
   __IwMain_from_arm
   $a
0x4a000058: e59fc004 .... LDR r12,[pc,#4] ; [0x4a000064] = 0x1be93ed
       0x4a00005c:    e08fc00c    ....    ADD      r12,pc,r12
       0x4a000060:    e12fff1c    ../.    BX       r12
   $d
       0x4a000064:    01be93ed    ....    DCD    29266925

The offset stored at 0x4a000064 is 0x1be93ed, which is way out of bounds of my program image. It seems to bear no relation to the actual target address its trying to get to (IwMain, at 4a03cd78)

When its OK it looks like this:
  s3e_start
   $a
       0x4a000000:    e92d4038    8@-.    PUSH     {r3-r5,r14}
       0x4a000004:    e31d0004    ....    TST      r13,#4
       0x4a000008:    03a05000    .P..    MOVEQ    r5,#0
       0x4a00000c:    13a05001    .P..    MOVNE    r5,#1
       0x4a000010:    124dd004    ..M.    SUBNE    r13,r13,#4
0x4a000014: eb002349 I#.. BL __libc_init_array ; 0x4a008d40
       0x4a000018:    eb000540    @...    BL       iwcrt_init  ; 0x4a001520
0x4a00001c: eb00000d .... BL __IwMain_from_arm ; 0x4a000058
       0x4a000020:    e1a04000    .@..    MOV      r4,r0
       0x4a000024:    e1a01000    ....    MOV      r1,r0
       0x4a000028:    e3a0000f    ....    MOV      r0,#0xf
       0x4a00002c:    eb000095    ....    BL       0x4a000288
       0x4a000030:    e1a00004    ....    MOV      r0,r4
       0x4a000034:    e3a01000    ....    MOV      r1,#0
0x4a000038: eb002126 &!.. BL __call_exitprocs ; 0x4a0084d8
       0x4a00003c:    eb000450    P...    BL       iwcrt_fini  ; 0x4a001184
0x4a000040: eb002197 .!.. BL __libc_fini_array ; 0x4a0086a4
       0x4a000044:    e3150001    ....    TST      r5,#1
       0x4a000048:    128dd004    ....    ADDNE    r13,r13,#4
       0x4a00004c:    e3a00000    ....    MOV      r0,#0
       0x4a000050:    e8bd4038    8@..    POP      {r3-r5,r14}
       0x4a000054:    e12fff1e    ../.    BX       r14
   __IwMain_from_arm
   $a
0x4a000058: e59fc004 .... LDR r12,[pc,#4] ; [0x4a000064] = 0x3fd
       0x4a00005c:    e08fc00c    ....    ADD      r12,pc,r12
       0x4a000060:    e12fff1c    ../.    BX       r12
   $d
       0x4a000064:    000003fd    ....    DCD    1021

In this case, IwMain is at 0x4a000460. The s3e_start function is coming from the same object file in both cases, so that eliminates the compiler output.

In general, it seems to go wrong with larger images, although I can't isolate a precise cause. In these cases if I make IwMain ARM code (so a veneer isn't needed), my application crashes at the next arm-thumb veneer, presumably with the same problem.

It could possibly be related to these problems: http://www.pubbs.net/gcc/200906/8641/

Maybe some memory overwrites going on in the linker?

Any workaround suggestions much appreciated.