Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cmake] Fix -z noexecstack portability #4222

Merged
merged 1 commit into from
Dec 20, 2024

Conversation

terrelln
Copy link
Contributor

@terrelln terrelln commented Dec 20, 2024

Summary:
Issue reported by @ryandesign and @MarcusCalhoun-Lopez. Thanks to @ryandesign for investigating this issue in-depth & making fixing it easy.

CMake doesn't support spaces in flags. This caused older versions of gcc to ignore the unknown flag "-z noexecstack" on MacOS since it was interpreted as a single flag, not two separate flags. Then, during compilation it was treated as "-z" "noexecstack", which was correctly forwarded to the linker. But the MacOS linker does not support -z noexecstack so compilation failed.

The fix is to use -Wl,-z,noexecstack. This is never misinterpreted by a compiler. However, not all compilers support this syntax to forward flags to the linker. To fix this issue, we check if all the relevant noexecstack flags have been successfully set, and if they haven't we disable assembly.

See also PR #4056 and PR #4061. I decided to go a different route because this is simpler. It might not successfully set these flags on some compilers, but in that case it also disables assembly, so they aren't required.

Test Plan:

mkdir build-cmake
cmake ../build/cmake/CMakeLists.txt
make -j

See that the linker flag is successfully detected & that assembly is enabled.

Run the same commands on MacOS which doesn't support -Wl,-z,noexecstack and see that everything compiles and that LD_FLAG_WL_Z_NOEXECSTACK and ZSTD_HAS_NOEXECSTACK are both false.

Summary:
Issue reported by @ryandesign and @MarcusCalhoun-Lopez.

CMake doesn't support spaces in flags. This caused older versions of gcc to
ignore the unknown flag "-z noexecstack" on MacOS since it was interpreted as a
single flag, not two separate flags. Then, during compilation it was treated as
"-z" "noexecstack", which was correctly forwarded to the linker. But the MacOS
linker does not support `-z noexecstack` so compilation failed.

The fix is to use `-Wl,-z,noexecstack`. This is never misinterpreted by a
compiler. However, not all compilers support this syntax to forward flags to the
linker. To fix this issue, we check if all the relevant `noexecstack` flags have
been successfully set, and if they haven't we disable assembly.

See also PR#4056 and PR#4061. I decided to go a different route because this is
simpler. It might not successfully set these flags on some compilers, but in that
case it also disables assembly, so they aren't required.

Test Plan:
```
mkdir build-cmake
cmake ../build/cmake/CMakeLists.txt
make -j
```

See that the linker flag is successfully detected & that assembly is enabled.

Run the same commands on MacOS which doesn't support `-Wl,-z,noexecstack` and see
that everything compiles and that `LD_FLAG_WL_Z_NOEXECSTACK` and
`ZSTD_HAS_NOEXECSTACK` are both false.
@Cyan4973
Copy link
Contributor

Cyan4973 commented Dec 20, 2024

Is there a test we could create in CI that would trigger the problem (without this PR) ?

@terrelln
Copy link
Contributor Author

I'm not sure. My understanding is that it requires quite an old version of gcc on MacOS to test. I'm not sure we'll be able to get a gcc old enough in our Mac test environment.

@terrelln terrelln merged commit f0937b8 into facebook:dev Dec 20, 2024
94 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants