在Solaris 64位上使用函数指针堆坏了

时间:2014-10-16 16:52:30

标签: c function-pointers solaris

我在使用CC 5.10编译的Solaris 5.10 64位上有以下C代码,标志为 -m64 -KPIC -x04

header.h

typedef struct functions
{
   double (* pfComputeGeneric) (myStruct *, myStruct *, double, double *, int);
} functions;

...

double myCompute(myStruct *, myStruct *, double, double *, int);  

由source.c

double myCompute(myStruct * px1, myStruct *px2, double d1, double *pd1, int i1)
{
    // Do stuff with px1
}

...

myStruct *pxStruct = alloc(...);    
functions *pxFunctions = alloc(...);
pxFunctions->pfComputeGeneric = myCompute;

...

double dResult += pxFunctions->pfComputeGeneric(pxStruct, pxStruct, 0.0, NULL, 0);

source.c 中的代码运行正常(没什么奇怪的),直到我通过函数指针 pfCompute 进入 myCompute ,其中 px1 被破坏。我不知道为什么。

通过直接调用 myCompute 来通过 pfCompute 替换调用解决了这个问题。

删除 -x04 选项也解决了这个问题。

我查看了this question的答案,但我确定我没有弄乱指针大小。

1 个答案:

答案 0 :(得分:1)

我认为这确实是 -x04 的问题。当我看到组合电话时,我看到了:

...
0x0000000000987eb2: myCaller+0x081a:  movq     0xfffffffffffffe28(%rbp),%rcx
0x0000000000987eb9: myCaller+0x0821:  movq     $0x0000000000000006,%rax
0x0000000000987ec0: myCaller+0x0828:  movq     0xfffffffffffffe08(%rbp),%rdi
0x0000000000987ec7: myCaller+0x082f:  call     *0x0000000000000018(%rdi)
0x0000000000987eca: myCaller+0x0832:  addq     $0x0000000000000010,%rsp

因此,编译器使用%rdi (!)从 pxFunctions 获取 myCompute 的真实地址。在64位中,%rdi 用于存储函数的第一个参数,因此进行了更改。