链接器标志之间的差异

链接器标志之间的差异

我正在向 Linux 内核添加 C++ 运行时和异常支持。为此,我需要提供我自己的库lib/gcc,而lib/libstdc++不是编译器提供的标准库。

因此,我对要传递给链接器的标志感到困惑。在普通内核的顶层Makefile中,LD = $(CROSS_COMPILE)ld它使内核能够使用默认的标准库和启动文件。对于我的内核,我LD = $(CROSS_COMPILE)ld -nostdlib -nodefaultlibs -nostartfiles按照文档中的说明使用。我从中了解到的海湾合作委员会文档传递-nostdlib给链接器就是传递两者-nodefaultlibs -nostartfiles。这些标志实际上有什么区别?

答案1

这些标志定义在GCC 的规范文件,因此确定它们之间差异的最佳方法是查看那里:

gcc -dumpspecs

相关部分是link_command定义。这表明-nostdlib-nodefaultlibs-nostartfiles具有以下影响:

  • %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}}— 这会根据需要添加libgcc, libpthread, libc,使用libieee以及liblibgccspec 字符串;
  • %{!nostdlib:%{!nostartfiles:%S}}— 这会添加startfile规范字符串 ,它指定要添加以处理启动的对象文件(crti.o等)
  • %{!nostdlib:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end} %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}— 这添加了虚拟表验证libvtv
  • %{!nostdlib:%{!nodefaultlibs:%{mmpx:%{fcheck-pointer-bounds: %{static:--whole-archive -lmpx --no-whole-archive %:include(libmpx.spec)%(link_libmpx)} %{!static:%{static-libmpx:-Bstatic --whole-archive} %{!static-libmpx:--push-state --no-as-needed} -lmpx %{!static-libmpx:--pop-state} %{static-libmpx:--no-whole-archive -Bdynamic %:include(libmpx.spec)%(link_libmpx)}}}}%{mmpx:%{fcheck-pointer-bounds:%{!fno-chkp-use-wrappers: %{static:-lmpxwrappers} %{!static:%{static-libmpxwrappers:-Bstatic} -lmpxwrappers %{static-libmpxwrappers: -Bdynamic}}}}}}}——这个处理libmpx
  • %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address): %{static-libasan:%:include(libsanitizer.spec)%(link_libasan)} %{static:%ecannot specify -static with -fsanitize=address}} %{%:sanitize(thread): %{static-libtsan:%:include(libsanitizer.spec)%(link_libtsan)} %{static:%ecannot specify -static with -fsanitize=thread}} %{%:sanitize(undefined):%{static-libubsan:-Bstatic} -lubsan %{static-libubsan:-Bdynamic} %{static-libubsan:%:include(libsanitizer.spec)%(link_libubsan)}} %{%:sanitize(leak): %{static-liblsan:%:include(libsanitizer.spec)%(link_liblsan)}}}}— 这处理各种消毒选项
  • %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}— 这会添加堆栈保护选项并重复 C 链接序列(其库已在开始时指定)
  • %{!nostdlib:%{!nostartfiles:%E}}— 这会添加endfile规范字符串,它指定要添加的对象文件以处理剩余内容(crtfastmath.ocrtend.o

正如您从文档中了解到的,是和-nostdlib的超集。它还禁用虚拟表验证。-nodefaultlibs-nostartfiles

因此-nostdlib足以禁用所有相关功能;-nodefaultlibs并且-nostartfiles不要向其中添加任何内容。 (但提及它们也没什么坏处。)

相关内容