C 什么是「-z";选择叮当声,为什么需要它?
考虑以下特定于链接器的Clang选项:C 什么是「-z";选择叮当声,为什么需要它?,c,macos,linker,clang,C,Macos,Linker,Clang,考虑以下特定于链接器的Clang选项: -Wl,<arg> Pass the comma separated arguments in <arg> to the linker -Xlinker <arg> Pass <arg> to the linker -z <arg> Pass -z <arg> to the linker 但是,如果-
-Wl,<arg> Pass the comma separated arguments in <arg> to the linker
-Xlinker <arg> Pass <arg> to the linker
-z <arg> Pass -z <arg> to the linker
但是,如果-Wl
的参数应该仅用逗号分隔,那么为什么需要这样做呢
为什么-z与-Wl一起使用
以下3个命令完全等效:
clang main.c -o a.out -Wl,-z,norelro
clang main.c -o a.out -z norelro
clang main.c -o a.out -Xlinker -z -Xlinker norelro
在最终链接阶段,它们都将-z norelro
传递给链接器
第一种形式是许多编译器的标准形式。第二种形式稍微短一点,但实际上不应该使用(因为使用“标准”形式总是更好)。支持第三种形式只是为了与GCC兼容。这是不必要的冗长
更新:
难道我们就不能写-Wl,norelro
否:这将向链接器传递一个“裸”norelro
选项,链接器将其视为输入文件,并将投诉不存在此类输入文件。通过-z norelro
和仅仅通过norelro
之间(显然)有区别
也可以考虑<代码> CLAN//NOASLR .C-WL,-Z,-NoPiple…< /代码>
那只是一个虚假的命令。-no pie
是一个链接器选项,不应以-z
作为前缀。对于-z
选项,它也是无效的选项值
更新2:
在哪里可以看到-z链接器选项的可能值
在目标操作系统上的ld
手册页中。例如,在Linux上,最新的BFDld
包含以下-z
选项:bndplt
,call nop prefix=…
,combreloc
,等等
另外,你知道为什么macOS上的man ld没有显示-z链接器选项吗
可能是因为它根本不支持这个选项。请注意,这种愚蠢几乎总是通过兼容性产生的。A组发明了标准A,B组发明了标准B,C组发明了标准C,突然你发现自己需要实现所有3个。。。现在是标准D。另请参阅,谢谢。但是为什么
-z
与-Wl
一起使用呢?难道我们不能只写-Wl,norelro
(在-Wl
的描述中没有提到-z
)?此外,为什么<代码> -Z 与<代码> - Xlinker < /代码>(它们有完全相同的描述)?还要考虑<代码> CLAN/NoasLR.C-WL,-Z,-NONEPI-O-NOASLR < /代码>,这导致<代码> LD:未知选项:-MAXOS上的-Z < /代码>。这只适用于没有-z
选项的情况,即-Wl,-no_pie
???再次感谢。我想我现在明白了链接器ld
使用-z
获取选项本身,并且clang
将-z
准确地传递给-ld
,而不仅仅是
?此外,链接器的某些参数需要-z
,而其他参数如-no_-pie
则完全按原样传递(前面没有-z
)?在哪里可以看到-z
链接器选项的可能值?另外,你知道为什么macOS上的manld
没有显示-z
链接器选项吗?谢谢,我想既然clang
支持macOS上的-z
,但是ld
中没有提到该选项,那么clang
必须将其转换为ld
理解的某个选项。
clang main.c -o a.out -Wl,-z,norelro
clang main.c -o a.out -z norelro
clang main.c -o a.out -Xlinker -z -Xlinker norelro