让GCC编译而不插入对memcpy的调用

Bri*_*ian 11 compiler-construction gcc libc memcpy

我目前正在使用GCC 4.5.3,为PowerPC 440编译,并且正在编译一些不需要libc的代码.我没有直接调用memcpy(),但编译器似乎在构建期间插入一个.

有一些链接器选项,如-nostdlib,-nostartfiles,-nodefaultlibs但我无法使用它们,因为我没有进行链接阶段.我只是在编译.有这样的事情:

$ powerpc-440-eabi-gcc -O2 -g -c -o output.o input.c
Run Code Online (Sandbox Code Playgroud)

如果我用nm检查output.o,我会看到对memcpy的引用:

$ powerpc-440-eabi-nm output.o | grep memcpy
     U memcpy
$ 
Run Code Online (Sandbox Code Playgroud)

GCC手册页明确了如何使用链接器删除对memcpy和其他libc调用的调用,但我不希望编译器首先插入它们,因为我使用的是完全不同的链接器(不是GNU的ld) ,它不知道libc).

感谢您的任何帮助,您可以提供.

Ric*_*ton 5

您需要使用-fno-builtin禁用该优化.尝试编译C库的memcpy时,我遇到过这个问题.它自称.哎呀!

  • 感谢您的回复!阅读完手册后,似乎 -fno-builtin 或 -ffreestand 应该完全满足我的需要。但添加这些编译器开关后,我仍然得到两个对 memcpy 的引用。还有其他建议吗? (2认同)

Dro*_*com 5

在某些情况下,Gcc会发出对memcpy的调用,例如,如果要复制结构.无法更改GCC行为,但您可以尝试通过修改代码来避免此类复制.最好的办法是查看程序集,找出为什么gcc发出memcpy并尝试解决它.这会很烦人,因为你基本上需要了解gcc是如何工作的.

摘自http://gcc.gnu.org/onlinedocs/gcc/Standards.html:

GCC使用的大多数编译器支持例程都存在于libgcc中,但也有一些例外.GCC要求独立环境提供memcpy,memmove,memset和memcmp.最后,如果使用了__builtin_trap,并且目标没有实现陷阱模式,那么GCC将发出中止调用.


tec*_*rus 5

有没有必要-fno-builtins或者-ffreestanding因为他们将禁用不必要的很多重要的优化

这实际上是由gcc的tree-loop-distribute-patterns“优化”的,因此要禁用有害行为,同时保留有用的内置功能,您可以使用:

-fno-tree-loop-distribute-patterns

MUSL-libc中使用此标志为它的构建,具有以下音符在他们的配置脚本(我通过源看,并没有发现任何的宏,所以这应该是足够了)

#检查可能需要的选项,以防止编译器
#生成memcpy,memmove,memcmp,
#和memset的自引用版本。确实,我们应该添加检查以确定此
#选项是否足够,否则,请添加一个宏以
使用volatile 削弱这些#函数。
#tryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns

您还可以使用其optimize属性将此属性添加为gcc中各个函数的属性,以便其他函数可以从调用中受益 mem*()