如何强制GCC在不需要时不包括对get_pc_thunk的调用

时间:2015-09-28 18:27:45

标签: c gcc optimization linker

我正在编写将被编译的代码(使用gcc,定位到Android x86),然后由另一个程序处理。该程序对其输入有限制,例如代码不能进行间接调用或引用全局变量。要在PIC / PIE代码中强制执行此操作,调用get_pc_thunk(或任何只读取堆栈顶部并返回的函数)的工具错误

我的代码处于满足这些要求的状态。所有函数都链接在一起,并且可以在链接后通过偏移调用。但是GCC在我的函数中调用了get_pc_thunk,即使它没有被使用。

我的代码是(test.c):

unsigned long long API test(unsigned long long a, unsigned long long b)
{
   return a / b;
}

构建这个我使用:

gcc.exe -o test.o -fno-stack-protector test.c -c -O0

gcc.exe -o libtest.so -m32 -static -static-libgcc -nostartfiles -shared test.o

我出去了:

000001d8 <test>:
 1d8:   55                      push   ebp
 1d9:   89 e5                   mov    ebp,esp
 1db:   53                      push   ebx
 1dc:   8d 64 24 dc             lea    esp,[esp-0x24]
 1e0:   e8 45 00 00 00          call   22a <__x86.get_pc_thunk.bx>
 1e5:   81 c3 0f 1e 00 00       add    ebx,0x1e0f
 1eb:   8b 45 08                mov    eax,DWORD PTR [ebp+0x8]
 1ee:   89 45 f0                mov    DWORD PTR [ebp-0x10],eax
 1f1:   8b 45 0c                mov    eax,DWORD PTR [ebp+0xc]
 1f4:   89 45 f4                mov    DWORD PTR [ebp-0xc],eax
 1f7:   8b 45 10                mov    eax,DWORD PTR [ebp+0x10]
 1fa:   89 45 e8                mov    DWORD PTR [ebp-0x18],eax
 1fd:   8b 45 14                mov    eax,DWORD PTR [ebp+0x14]
 200:   89 45 ec                mov    DWORD PTR [ebp-0x14],eax
 203:   8b 45 e8                mov    eax,DWORD PTR [ebp-0x18]
 206:   8b 55 ec                mov    edx,DWORD PTR [ebp-0x14]
 209:   89 44 24 08             mov    DWORD PTR [esp+0x8],eax
 20d:   89 54 24 0c             mov    DWORD PTR [esp+0xc],edx
 211:   8b 45 f0                mov    eax,DWORD PTR [ebp-0x10]
 214:   8b 55 f4                mov    edx,DWORD PTR [ebp-0xc]
 217:   89 04 24                mov    DWORD PTR [esp],eax
 21a:   89 54 24 04             mov    DWORD PTR [esp+0x4],edx
 21e:   e8 0b 00 00 00          call   22e <__udivdi3>
 223:   8d 64 24 24             lea    esp,[esp+0x24]
 227:   5b                      pop    ebx
 228:   5d                      pop    ebp
 229:   c3                      ret    

0000022a <__x86.get_pc_thunk.bx>:
 22a:   8b 1c 24                mov    ebx,DWORD PTR [esp]
 22d:   c3                      ret    

0000022e <__udivdi3>:
 ...

通过了解正在发生的事情我明白在编译时gcc为get_pc_thunk和__udivdi3调用添加占位符,因为它不知道__udivdi3将在哪一点,并且可能需要通过查找表调用。但是在链接之后不再需要get_pc_thunk。我查看了链接器选项,但找不到可以优化此调用的选项。

在这种情况下是否可以选择删除此不需要的电话?

1 个答案:

答案 0 :(得分:1)

对于Android NDK版本的gcc,有一个-fno-pic选项,允许在这种特殊情况下禁用PIC。