-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[cmake] Work around relocation R_X86_64_PC32 link error #2012
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] Work around relocation R_X86_64_PC32 link error #2012
Conversation
Looks OK to me (though @gribozavr is a better CMake-r than me). We'll also need something in the driver to pass these flags if the linker needs them too. That would need to be some kind of runtime check, though. |
@@ -1774,6 +1787,18 @@ function(_add_swift_executable_single name) | |||
list(APPEND link_flags "-fuse-ld=gold") | |||
endif() | |||
|
|||
INCLUDE(CheckCXXCompilerFlag) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually don't think this block is required. I merely included it because I think it might be. Someone who understands the CMake scripts a little better might be able to quickly deduce its necessity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this block is necessary. This function is used to configure compiler executables, which don't have any Swift code in them.
@jckarter I don't yet understand how the driver works in order to write that code. I'm interested in trying to fix that piece as well (as a separate pull). I just figured I'd start with the piece I do somewhat understand and can test and validate. |
One thing, there's no reason to do this check when building to target OS X; it's only necessary if targeting ELF platforms (or maybe only Linux, if the binutils brain damage didn't make it out to *BSD). |
Fair enough about making the driver change separately. It'd be good to note that in the PR. |
CHECK_CXX_COMPILER_FLAG("" LINKER_SUPPORTS_NOEXTERN_PROTECTED_DATA) | ||
IF(LINKER_SUPPORTS_NOEXTERN_PROTECTED_DATA) | ||
list(APPEND link_flags ${CMAKE_REQUIRED_FLAGS}) | ||
ENDIF() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you should include()
or run tests in this function. This function is executed many times.
You should run the test once in the top-level CMakeLists.txt.
Also, our CMake code uses lowercase for function names, and two spaces for indentation, could you make it consistent?
b2fc5eb
to
ca5808d
Compare
I've rebased on master and pushed up a new attempt that incorporates the feedback. @jckarter I've moved the test for the linker flag inside of an @gribozavr I've created a new CMake module, I believe I've also addressed the styling changes you've requested. |
ca5808d
to
84de260
Compare
Thank you! Could you prefix global variables with |
84de260
to
63c702c
Compare
Updated to Thank you for taking the time to review @jckarter and @gribozavr. |
@@ -419,6 +420,12 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") | |||
set(SWIFT_HOST_VARIANT_SDK "LINUX") | |||
set(SWIFT_PRIMARY_VARIANT_SDK_default "LINUX") | |||
|
|||
# Support dynamic relocation in binutils >= 2.26 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More precisely, we're supporting "relative relocation against protected symbols in binutils 2.26". Give them the benefit of the doubt that 2.27 might be fixed.
LGTM too, with a fix to the comment. |
function(check_linker_supports_flag flag_to_test var_name) | ||
set(CMAKE_REQUIRED_FLAGS "${flag_to_test}") | ||
check_cxx_compiler_flag("" LINKER_SUPPORTS_NOEXTERN_PROTECTED_DATA) | ||
if(LINKER_SUPPORTS_NOEXTERN_PROTECTED_DATA) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variable name LINKER_SUPPORTS_NOEXTERN_PROTECTED_DATA
is not relevant for here.
result
would be sufficient I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I could have swore I replied to this already but apparently not.)
If I change it to result
than the check in the CMake output is less meaningful. It displays something like
...
Performing Test result
Performing Test result - Success
...
as opposed to
...
Performing Test LINKER_SUPPORTS_NOEXTERN_PROTECTED_DATA
Performing Test LINKER_SUPPORTS_NOEXTERN_PROTECTED_DATA - Success
...
If you still think it is worth it than I'm amenable to the change but I think it provides a less clear description of what is going on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I understand that.
And I found CMake caches the result of check_cxx_compiler_flag
associated with the variable name.
Because of that, if "-Wl,-z,nocopyreloc"
failed, then "-Wl,-z,noextern-protected-data"
fails without actual test.
To prevent that, <var>
for every tests must have unique names.
For example:
function(check_linker_supports_flag flag_to_test var_name)
set(CMAKE_REQUIRED_FLAGS "${flag_to_test}")
check_cxx_compiler_flag("" ${var_name})
if(${${var_name}})
set("${var_name}" TRUE PARENT_SCOPE)
else()
set("${var_name}" FALSE PARENT_SCOPE)
endif()
endfunction()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I should clarify the problem. For example:
cmake_minimum_required(VERSION 2.8.12)
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-static" RESULT)
message("RESULT_STATIC: ${RESULT}")
check_cxx_compiler_flag("-FOO-BAR" RESULT)
message("RESULT_FOOBAR: ${RESULT}")
This CMakeLists.txt
outputs:
-- Performing Test RESULT
-- Performing Test RESULT - Success
RESULT_STATIC: 1
RESULT_FOOBAR: 1
The second check_cxx_compiler_flag()
is no-op and just returns cached RESULT
value.
Generated CMakeCache.txt
contains
//Test RESULT
RESULT:INTERNAL=1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rintaro wonderful catch! Yes.
-- Performing Test SWIFT_LINKER_SUPPORTS_NOCOPYRELOC
-- Performing Test SWIFT_LINKER_SUPPORTS_NOCOPYRELOC - Success
-- Performing Test SWIFT_LINKER_SUPPORTS_NOEXTERN_PROTECTED_DATA
-- Performing Test SWIFT_LINKER_SUPPORTS_NOEXTERN_PROTECTED_DATA - Success
Much, much better. Thank you.
5c81539
to
63ae486
Compare
281b050
to
59d2e56
Compare
b15f541
to
2ff13c6
Compare
2ff13c6
to
650791d
Compare
A more complete discussion of the error and its background can be found in SR-1023. The brief overview is that in versions of `ld` that would be effected by this dynamic relocation issue there are two flags: `-z nocopyreloc` and `-z noextern-protected-data`. If `ld` supports the flags then they are sento to the linker. This patch checks that the linker supports the flags and then optionally sets them. The code to check if `ld` supports the flags is inspired by this CMake mailing list entry. https://cmake.org/pipermail/cmake/2011-July/045525.html
650791d
to
cabe7c4
Compare
What's in this pull request?
This is the first patch to begin working around the dynamic resolution of protected symbols. This behavior was introduced in
binutils
2.26.A more complete discussion of the error and its background can be found in SR-1023.
The brief overview is that in versions of
ld
that would be effected by this dynamic relocation issue there are two flags:-z nocopyreloc
and-z noextern-protected-data
. Ifld
supports the flags then they are sent to the linker. This patch checks that the linker supports the flags and then optionally sets them.The code to check if
ld
supports the flags is inspired by this CMake mailing list entry.https://cmake.org/pipermail/cmake/2011-July/045525.html
Resolves bug number: (SR-1023)
While this pull does not entirely resolve SR-1023 I do think it is a good first step.Update 1: I've now provided a Driver patch too. This branch should now work on binutils 2.26 (e.g., Ubuntu 16.04). The patch does not work on binutils builds that do not support these flags (e.g., Ubuntu 14.04/15.10). A conditional still needs to be written for the Driver to apply the new flags conditionally. I'm looking for feedback on how to best address that.
Before merging this pull request to apple/swift repository:
Triggering Swift CI
The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:
Smoke Testing
Validation Testing
Note: Only members of the Apple organization can trigger swift-ci.