gcc Cortex M4 bug ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
Im trying to implement a dynamic linker for M4 mcu's.
But the generated code from gcc seems incorrect to me: im compiling using
arm-none-eabi-gcc: -mcpu=cortex-m4 -mthumb -O2 -ggdb  -Wstrict-prototypes 
-Wunused-parameter -lmylib main.c -o test

Ive created the following program dynamically linked:
----main.c---------
int main()
{
        test();
        return 1;
}

On target I have the function
-------mylib.c-----------
int test()
{
        return 1;
}
arm-none-eabi-gcc -fPIC -mcpu=cortex-m4 -mthumb -O2 -ggdb 
-Wstrict-prototypes -Wunused-parameter -lmylib mylib.c -o mylib.so

------linker script-----
OUTPUT_FORMAT("elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)

PHDRS
{
        headers PT_PHDR PHDRS ;
        interp PT_INTERP ;
        text PT_LOAD FILEHDR PHDRS ;
        data PT_LOAD ;
        got PT_LOAD;
        dynamic PT_DYNAMIC ;
}

SECTIONS
{
        . = SIZEOF_HEADERS;
        .interp : { *(.interp) } :text :interp
        .hash           : { *(.hash) }
        .text : { *(.text) } :text
        .rodata : { *(.rodata) } /* defaults to :text */
        .dynsym         : { *(.dynsym) }
        .dynstr         : { *(.dynstr) }
        .rel.dyn        :
    {
      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
      *(.rel.got)
    }
        .rela.dyn       :
    {
      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
      *(.rela.got)
    }
        .rel.plt        :
    {
      *(.rel.plt)
    }
        .rela.plt       :
    {
      *(.rela.plt)
    }
  .init_array     :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array))
    PROVIDE_HIDDEN (__init_array_end = .);
  }
  .fini_array     :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array))
    PROVIDE_HIDDEN (__fini_array_end = .);
  }
  .jcr            : { KEEP (*(.jcr)) }

        .init           :
        {
                KEEP (*(.init))
        } =0
 .plt            :  { *(.plt) }
        .dynamic : { *(.dynamic) } :data :dynamic
        .got            : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } 
:got
        .data : { *(.data) } :data
}

the machine generated code for main looks as follows (objdump -D):

0000015c <main>:
 15c:   b508            push    {r3, lr}
 15e:   f000 e888       blx     270 <__libc_fini_array+0xfc>
 162:   2001            movs    r0, #1
 164:   bd08            pop     {r3, pc}
 166:   bf00            nop


instruction at  15e:   seems incorrect to me, since M4 only branches using 
a register   blx{cond} Rm, (M3 seems to be ok with label aswell.)

Anyone who can tell me what is wrong and if there is a workaround for this 
?

Ive tried to use -mlong-calls, and it produces:

00000164 <main>:
 164:   b508            push    {r3, lr}
 166:   f240 237c       movw    r3, #636        ; 0x27c
 16a:   f2c0 0300       movt    r3, #0
 16e:   4798            blx     r3
 170:   2001            movs    r0, #1
 172:   bd08            pop     {r3, pc}


This looks OK except for the address in R3 not being rellative, since it's 
absolute it's not correct either (or am I missing something)



BR
Matias




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux