clinkerpowerpccodewarrioreabi

Using FreeScale Code Warrior to link GCC object files with __eabi calls in main


I'm linking with FreeScale Code Warrior 5.9 for MPC5554, which is a PPC chip with an e500mc core. I'm compiling with GCC 4.6.4 compiled for powerpc-none-eabi.

I am compiling some C code for my project, including the file with main, using a GCC cross compiler. I need to link using Code Warrior, though. GCC adds a call to a function called __eabi at the start of main, which is supposed to initialize a couple of registers. It cannot be removed, and is unnecessary for what I'm doing. GCC expects it to be provided by the crt.

These are my compile flags for GCC: -O2 -std=c99 -w -mno-eabi -mregnames -mcpu=e500mc -misel=yes -mfloat-gprs=single -mno-string -msdata=none

The documentation for GCC PowerPC says there is a -no-eabi argument, which should remove this, but then if you dig into it there are a number of bugs reports pointing out that the documentation is wrong and the flag does not actually remove the call to __eabi.

I tried simply adding an __eabi function to the crt from CodeWarrior. In __ppc_eabi_init.c I added the function:

asm extern void __eabi(void)
{
    addis   r13,r0,_SDA_BASE_@h
    ori     r13,r13,_SDA_BASE_@l
    addis   r2,r0,_SDA2_BASE_@h
    ori     r2,r2,_SDA2_BASE_@l
    blr
}

However, when I try to link, I still get the error that __eabi from main in main.o is undefined. It seems the Code Warrior linker can't find my function. I verified that __ppc_eabi_init.c is first in the link order.

How can I get this to link? Is there a way to remove the call to __eabi? Why is Code Warrior unable to find the function when I provide it?


Solution

  • It turned out that I had the right idea, but that I was accidentally putting the __eabi function definition inside an #ifdef block that was being excluded from assembly. When I moved the definition outside this block it linked properly.

    I also modified the provided linker scripts so they would correctly locate the .rodata.cst* sections that GCC uses for read-only data. I am not sure this was important, but I was getting a warning from the linker, so I fixed it.

    In MPC5554.lcf, I changed

    .rodata (CONST) : {
        *(.rdata)
        *(.rodata)
    }
    

    to read

    .rodata (CONST) : {
        *(.rdata)
        *(.rodata)
        *(.rodata.cst*)
    }