4

Consider the following linker-specific options of 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

What is meant by Pass -z <arg> to the linker and how does -z <arg> differ from -Xlinker <arg>?

I sometimes see -z <arg> used with -Wl,<arg> like:

-Wl,-z,norelro

But why is this needed, if arguments to -Wl should merely be comma-separated?

sepp2k
  • 363,768
  • 54
  • 674
  • 675
Shuzheng
  • 11,288
  • 20
  • 88
  • 186
  • https://stackoverflow.com/questions/7880812/complete-list-of-clang-flags – gstukelj Oct 25 '19 at 07:04
  • Note that this sort of silliness almost always arises through compatibility. Group A invents standard A, group B invents standard B, group C invents standard C, and suddenly you find yourself needing to implement all 3 ... which is now standard D. See also https://xkcd.com/927/ – torek Oct 25 '19 at 23:26

1 Answers1

8

why is -z used with -Wl

The following 3 commands are exactly equivalent:

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

They all pass -z norelro to the linker during the final link stage.

The first form is standard across many compilers. The second form is a tiny bit shorter, but really shouldn't be used (because using a "standard" form is always better). The third form is supported only to be compatible with GCC. It's unnecessarily verbose.

Update:

Couldn't we just write -Wl,norelro

No: that will pass a "naked" norelro option to the linker, which will treat it as an input file and will complain that no such input file exists. There is (obviously) a difference between passing -z norelro and just norelro.

Also, consider clang ./noaslr.c -Wl,-z,-no_pie ...

That is just a bogus command. The -no-pie is a linker option, and should not be prefixed by -z. It's also not a valid option value for the -z option.

Update 2:

Where can I see possible values for the -z linker option?

In the manual page for ld on the OS that you are targeting. For example, on Linux the latest BFD ld understands the following -z options: bndplt, call-nop-prefix=..., combreloc, etc. etc.

Also, do you have any clue why man ld on macOS doesn't show the -z linker option?

Probably because it doesn't support that option at all.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Thanks. But why is `-z` used with `-Wl`? Couldn't we just write `-Wl,norelro` (nothing is mentioned about `-z` in the description of `-Wl`)? Also, why is `-z` used with `-Xlinker` (they have exactly the same description)? – Shuzheng Oct 26 '19 at 10:06
  • Also, consider `clang ./noaslr.c -Wl,-z,-no_pie -o noaslr` which results in `ld: unknown option: -z` on macOS. This only works without the `-z` option, i.e `-Wl,-no_pie`??? – Shuzheng Oct 26 '19 at 14:50
  • Thanks again. I think I understand now that the linker `ld` takes options itself using `-z ` and that `clang` pass exactly `-z ` to `ld` instead of only ``? Also, some arguments to the linker require `-z`, while others like `-no_pie` are passed exactly as they are (no `-z` in front)? Where can I see possible values for the `-z` linker option? Also, do you have any clue why `man ld` on macOS doesn't show the `-z` linker option? – Shuzheng Oct 27 '19 at 10:13
  • Thanks, I guess since `clang` supports `-z` on macOS, but nothing is mentioned about that option in `ld`, then `clang` must translate it to some option that `ld` understands. – Shuzheng Oct 27 '19 at 15:58