C 什么是「-z";选择叮当声,为什么需要它?

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 但是,如果-

考虑以下特定于链接器的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
的参数应该仅用逗号分隔,那么为什么需要这样做呢

为什么-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上,最新的BFD
ld
包含以下
-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