Delphi XE6 link C code in iOS

IosCDelphiPascalDelphi Xe6

Ios Problem Overview


I've built an App on Android using Delphi XE6 that requires C code. However on iOS I cannot make it work. I suspect the problem is related to arm/thumb status, but I am not sure. There is no problem in either system to call the C code from Pascal. But if the C code calls back a Pascal procedure iOS generates a "bad system call (12)"

Here is the pascal code:

function testarm(a,b:integer):integer; cdecl; external "testC.o";
    
Procedure testC;
Begin
  testarm(1,2);
end;
        
function BackToPascal(a,b:integer): integer; cdecl;
  Begin
  result := a+b;
end;
    
......
    
exports
  BackToPascal;
    

And here is the C code:

extern int BackToPascal(int a,int b);

extern int testarm(int a,int b)
{
   int i;
   i = BackToPascal(a,b);
   return i+1;
}

On android this is how I am compiling (It is working):

..."arm-linux-androideabi-gcc.exe" -c test.c -o test.o -O3 -mfloat-abi=softfp -mfpu=neon -marm -march=armv7-a -mtune=cortex-a8

On ios:

xcrun -sdk iphoneos clang -c -arch armv7 test.c -O3 -mfpu=neon -mtune=cortex-a8 -marm -march=armv7-a -mfloat-abi=softfp

I suspect that my xcode settings are wrong but I cannot figure out why.

When I debug, the error comes when calling testC in testarm when calling BackToPascal ( on "bl 0x8b8390 Xgobj.BackToPascal (int, int)" ). On Android it works perfect however the bl does not call directly BackToPascal, but the following code:

75A82D94 12C68FE2         add r12, pc, #18874368 ; 0x1200000
75A82D98 73CA8CE2         add r12, r12, #471040 ; 0x73000
75A82D9C 40F2BCE5         ldr pc, [r12, #576]! ; 0x240

Which get into BackToPascal

Ios Solutions


Solution 1 - Ios

The code looks proper and your calling convention handling is, to my eyes, perfectly correct.

I think you may have ran into a possible/rumoured bug in Apple's ARM clang where calling a static function (which may happen behind the scenes e.g. for type conversion) from a static function may cause stack corruption. You're not doing so directly, but extern functions may be implemented through a stub which calls an anonymous static function containing the implementation.

You can try having your extern function be a wrapper which only calls a non-static implementation function instead.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionXavier Dufaure de CitresView Question on Stackoverflow
Solution 1 - IosSianaView Answer on Stackoverflow