This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Indirect branch and function attributes

Hi to everyone,

i am trying to use pointer functions to do indirect branch in C code, i am working with an NXP ARM LPC2478

This is my code:


// in internal flash
unsigned char* MD5BuffSE(unsigned char *pBuffer, unsigned long lOffset, unsigned long lSize)
{
   ...
}

g_CriptAddress.pMd5 = (void*)&MD5BuffSE; // g_CriptAddress is an array of void*


.....

// in internal ram @ 0x4000fd00
typedef unsigned char* (*MD5)(unsigned char* , unsigned long , unsigned long );
MD5 Md5 = (MD5)g_CriptAddress.pMd5;

if(memcmp(Md5((byte*)TOS_START, 0, TOS_DIM),pDataProt->ChkSumMd5,16)!=0)
        return false;

with this code all seems to works fine (code jumps to the right address and returns well), but next branch causes execution to fail with an abort exception.

if i use MD5BuffSE directly all works, but i noticed that compiler insert a long ARM to ARM veneer

so i ask myself if exist a way to tell compiler that it has to consider typedef MD5 a far call or to force it to create a long ARM to AMR veneer

what happens when i call a thumb function from arm code with indirect branch?

Lorenzo

Parents
  • [LPC2478 is an ARM7TDMI.]

    A call via a function pointer will typically generate ADR lr, ...; BX <reg>* which needs no veener and can handle pointers to ARM state and Thumb state functions as long as the target function has been built for interworking (that is, uses BX <reg> to return). If the target function is in ARM state the low two bits of the function pointer will be zero. If the target function is in Thumb state the lowest bit of the function pointer will be one.

    When you say "but next branch causes execution to fail with an abort exception" do you mean the next branch, the next call of any function or the next call via that function pointer?

    If you mean the next call via that function pointer then I would suspect that your function pointer had been overwritten somehow -- can you check its value when it works and when things go wrong?

    [*] or just BLX <reg> on newer cores

    [By the way, I agree that casts are evil and best avoided whenever possible -- and not just for function pointers.]

Reply
  • [LPC2478 is an ARM7TDMI.]

    A call via a function pointer will typically generate ADR lr, ...; BX <reg>* which needs no veener and can handle pointers to ARM state and Thumb state functions as long as the target function has been built for interworking (that is, uses BX <reg> to return). If the target function is in ARM state the low two bits of the function pointer will be zero. If the target function is in Thumb state the lowest bit of the function pointer will be one.

    When you say "but next branch causes execution to fail with an abort exception" do you mean the next branch, the next call of any function or the next call via that function pointer?

    If you mean the next call via that function pointer then I would suspect that your function pointer had been overwritten somehow -- can you check its value when it works and when things go wrong?

    [*] or just BLX <reg> on newer cores

    [By the way, I agree that casts are evil and best avoided whenever possible -- and not just for function pointers.]

Children
  • thanks to all, i found what was wrong and it was a problem caused by MY code.
    so problem solved

    thank to you scott, 'cause you clean all my doubts about indirect branch and Veneer generation

    "A call via a function pointer will typically generate ADR lr, ...; BX <reg>* which needs no veener and can handle pointers to ARM state and Thumb state functions as long as the target function has been built for interworking (that is, uses BX <reg> to return)."

    thank to you Hans for the tip about function pointers, now compiler alerts if i call a function with wrong parameters

    problem: code in ram corrupts itself and stack generates an abort exception on next return