Skip to content

cmake: linker: make passing -no-pie configurable#54445

Merged
nashif merged 12 commits intozephyrproject-rtos:mainfrom
dcpleung:linker/no_pie_native_posix_only
Mar 29, 2023
Merged

cmake: linker: make passing -no-pie configurable#54445
nashif merged 12 commits intozephyrproject-rtos:mainfrom
dcpleung:linker/no_pie_native_posix_only

Conversation

@dcpleung
Copy link
Copy Markdown
Member

@dcpleung dcpleung commented Feb 3, 2023

(See individual commits for details.)

The main issue is to properly pass -no-pie (or --no-pie) to the linker. Old binutils' ld (<= 2.36, used in Ubuntu 20.04) and XCC's xt-ld both do not support '-no-pie' in linker. If you pass '-no-pie' to them, they will be parsed separately as -n and -o-pie, which results in output file named -pie instead of the usual zephyr*.elf (and thus failing intermediate build steps). The rest of the commits are to make llvm/clang works in CI and to fix a partially non-functional CONFIG_LLVM_USE_LD.

andyross
andyross previously approved these changes Feb 3, 2023
Copy link
Copy Markdown
Contributor

@andyross andyross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This definitely gets my vote

aborisovich
aborisovich previously approved these changes Feb 5, 2023
Copy link
Copy Markdown

@aborisovich aborisovich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And my axe 😆

nordicjm
nordicjm previously approved these changes Feb 6, 2023
Copy link
Copy Markdown
Contributor

@tejlmand tejlmand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a bit more description to fully understand the use-case.

Also, this should be having corresponding Kconfig setting, and not rely on board testing directly in CMake.

Comment thread cmake/linker/ld/target_base.cmake Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first comment.
We should not filter this based on a board type.
It's to limiting regarding users ability to enable / disable this flag.

As minimum this should have a Kconfig and with a proper default value.
A given board can then define a different default.

The setting may be promptless to avoid users accidentially changing the setting.

Comment thread cmake/linker/ld/target_base.cmake Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

your commit message states:

Zephyr SDK and others are, currently, not to produce PIE binaries by default.

I get that if Zephyr SDK and other currently do not produce PIE binaries per default, but what is the problem in specifying the flag in those cases then ?

Also, we are explicitly requesting the compiler to not do position independent code for C code here:

zephyr/CMakeLists.txt

Lines 376 to 377 in ab764aa

# @Intent: Do not make position independent code / executable
zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,no_position_independent>>)

so having -no-pie for the linker seems logical to me in this case, even though the toolchain you mention does so per default.

Is your intention to be able to actually use -pie on the linker in some use-cases ?

Or should we actually change the handling of pie / -no-pie, so that it compiler and linker flags are set as properties and then applied based on configuration.
Similar to how things are done for coverage, where the are both compiler and linker flags specified under the coverage property, which is then applied based on Kconfig.
Ref:

if(CONFIG_COVERAGE)
zephyr_compile_options($<TARGET_PROPERTY:compiler,coverage>)
zephyr_link_libraries($<TARGET_PROPERTY:linker,coverage>)
endif()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so having -no-pie for the linker seems logical to me in this case, even though the toolchain you mention does so per default.

Is your intention to be able to actually use -pie on the linker in some use-cases ?

Answering my own question.
I see the need for not passing the flag here: #54333 (comment)

So atm it seems to be specific to the Xtensa toolchain, xcc.
Which means the best approach forward is to have a no_position_independent property also on the linker, and the Xtensa toolchain can then set this property flag to empty in https://github.com/zephyrproject-rtos/zephyr/tree/main/cmake/linker/ld/xcc/linker_flags.cmake (assuming the xcc uses the ld linker)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we need this with LLVM as well. So it might not be xcc specific.

@tejlmand
Copy link
Copy Markdown
Contributor

tejlmand commented Feb 6, 2023

Need a bit more description to fully understand the use-case.

Also, this should be having corresponding Kconfig setting, and not rely on board testing directly in CMake.

The Kconfig part may not be required.
Seems to be toolchain related, and hence the toolchain properties should be defined properly.

Of course if a better user-facing handling of when to apply the properties is desired, then those should go through Kconfig as described. But the immediate problem described in #54333 doesn't seem to need it.

@andyross
Copy link
Copy Markdown
Contributor

andyross commented Feb 6, 2023

I get that if Zephyr SDK and other currently do not produce PIE binaries per default, but what is the problem in specifying the flag in those cases then ?

Others can comment with more expertise, but the core issue is that this flag isn't supported compatibly across all binutils/gcc/clang/lld variants. And we don't really want it anyway, it's not a feature we enable at code generation so we don't want the linker to have to care about it.

The sole exception (I think! @yperess caught this originally) is on Debian when using the distro-provided clang/lld to produce native_posix binaries. There, the toolchain is hard-wired to generate pic/pie by default, so we need the flag to the linker to unbreak things. But that requires per-toolchain hackery.

I think.

@dcpleung dcpleung dismissed stale reviews from nordicjm, aborisovich, and andyross via fd56ba0 February 6, 2023 21:07
@dcpleung dcpleung force-pushed the linker/no_pie_native_posix_only branch from 2f0b6aa to fd56ba0 Compare February 6, 2023 21:07
@dcpleung dcpleung changed the title cmake: linker: limit -no-pie to native_posix cmake: linker: make passing -no-pie configurable Feb 6, 2023
@dcpleung
Copy link
Copy Markdown
Member Author

dcpleung commented Feb 6, 2023

@tejlmand I have updated the PR to use linker property. I tried this previously but was having issue with using zephyr_ld_options(). Using zephyr_link_libraries() got past that issue.

@marc-hb
Copy link
Copy Markdown
Contributor

marc-hb commented Feb 6, 2023

There [on Debian], the toolchain is hard-wired to generate pic/pie by default, so we need the flag to the linker to unbreak things. But that requires per-toolchain hackery.

Stating the obvious: this was done to increase security
https://wiki.debian.org/Hardening/PIEByDefaultTransition
https://wiki.ubuntu.com/SecurityTeam/PIE

A lot of background information on these pages, including this (not) fun bit:

Note that some of these packages have already taken patches upstream from distros that were using patched versions of GCC that enabled PIE by default and added a GCC option -nopie to disable it. However, upstream GCC has settled on the -no-pie option as the means for disabling PIE when GCC is configured to use it by default.

Similar headaches:

@dcpleung
Copy link
Copy Markdown
Member Author

dcpleung commented Feb 6, 2023

I think something is wrong in cmake scripts... the error said it was using /usr/bin/ld, but yet the LLD linker cmake files were parsed instead. Locally, ld.lld is always picked up, and ld is never used. I am on Ubuntu 22.04.1, clang 15.0.6, cmake 3.20.5.

@tejlmand
Copy link
Copy Markdown
Contributor

tejlmand commented Feb 7, 2023

I tried this previously but was having issue with using zephyr_ld_options().

Yes, because that function was made to be able to check if a flag is valid, so it only handles simply flags and not generator expressions.

Using zephyr_link_libraries() got past that issue.

yes, and this is the function to use now, because code is updated to use linker properties.

I think something is wrong in cmake scripts... the error said it was using /usr/bin/ld, but yet the LLD linker cmake files were parsed instead.

Sounds strange. Will see if I can re-produce.

@dcpleung dcpleung force-pushed the linker/no_pie_native_posix_only branch from fd56ba0 to 34e2251 Compare February 7, 2023 09:38
@dcpleung
Copy link
Copy Markdown
Member Author

dcpleung commented Feb 7, 2023

I think something is wrong in cmake scripts... the error said it was using /usr/bin/ld, but yet the LLD linker cmake files were parsed instead.

Sounds strange. Will see if I can re-produce.

Turns out if you only have LLVM/clang/lld 15 installed, the symlink /usr/bin/ld.lld would not be there as it comes from package lld (which pulls in lld-14). Therefore, using find_program() to find ld.lld would not work since it's no in PATH. CMake then defaults to using /usr/bin/ld. I think this is what is causing the build failure. I have added a commit to expand the search to LLVM_TOOLCHAIN_HOME/bin (which basically is TOOLCHAIN_HOME).

However, another issue is that CONFIG_LLVM_USE_LD=y does not have any effect. I am not totally sure why... my guess is that the cmake scripts under cmake/toolchain is parsed before kconfigs, and none of CONFIG_* exist.

@dcpleung
Copy link
Copy Markdown
Member Author

dcpleung commented Feb 7, 2023

Errr... the new commit doesn't seem to work with the Clang/LLVM workflow.

@dcpleung dcpleung force-pushed the linker/no_pie_native_posix_only branch from 34e2251 to 5c1f16a Compare February 12, 2023 10:45
@dcpleung
Copy link
Copy Markdown
Member Author

I have updated the PR to use find_package() for both ld and lld.

@dcpleung dcpleung force-pushed the linker/no_pie_native_posix_only branch from b2fba48 to 3d0e221 Compare February 26, 2023 00:23
Copy link
Copy Markdown
Contributor

@tejlmand tejlmand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, nice improvement.

Some general comments, but I've found no major issues.

Comment thread cmake/toolchain/llvm/Kconfig Outdated
Comment thread cmake/toolchain/llvm/Kconfig Outdated
Comment thread cmake/toolchain/llvm/target.cmake Outdated
Comment on lines 7 to 9
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really needed ?
A choice will always have a value, so the only way that both CONFIG_LLVM_USE_LD and CONFIG_LLVM_USE_LLD could n is in case someone extended the choice with an extra config option.
And in case someone does that there probably have a very good reason to do so.

Finally, fatal errors should be used with absolute caution when it comes to Kconfig settings because of #9573

Suggested change
else()
message(FATAL_ERROR
"Need to enable either CONFIG_LLVM_USE_LD or CONFIG_LLVM_USE_LLD!")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really needed ? A choice will always have a value,...

Unless when editing the .config file manually or generating from fragments and some non-Zephyr script?

so the only way that both CONFIG_LLVM_USE_LD and CONFIG_LLVM_USE_LLD could n is in case someone extended the choice with an extra config option.

Could someone really add an extra KConfig option without editing this code?

Finally, fatal errors should be used with absolute caution when it comes to Kconfig settings because of #9573

I only skimmed 9573 sorry but the main message seems to be "don't generate invalid .config files that menuconfig" can't read again. It will of course always be possible to make invalid .config edits manually.

Can this FATAL_ERROR really cause invalid .config files to be generated?

In my experience CMake and Kconfig errors tend to be a nightmare to debug + no one wants to go anywhere near them. Very understandable when you look at major design mistakes like COMMAND_ERROR_IS_FATAL false by default, MYPROGRAM_NOT-FOUND and other crazy and super time-consuming CMake stuff like https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/

So in general we need MORE user-friendly error messages, not fewer but maybe this particular case is different? Not convinced of that yet.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone adds a new linker kconfig, this acts as a reminder that this also needs to be changed. I will change it to a warning instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless when editing the .config file manually or generating from fragments and some non-Zephyr script?

No, it will always be set, try this for yourself:

$ cat build/zephyr/.config |grep LLVM_USE
CONFIG_LLVM_USE_LD=y
# CONFIG_LLVM_USE_LLD is not set
$ sed 's/\(CONFIG_LLVM_USE_LD\)=y/# \1 is not set/g' build/zephyr/.config > tmp; mv tmp build/zephyr/.config
$ cat build/zephyr/.config |grep LLVM_USE
# CONFIG_LLVM_USE_LD is not set
# CONFIG_LLVM_USE_LLD is not set

.... Let's do the build:
$ ninja -Cbuild
ninja: Entering directory `build'
[0/1] Re-running CMake...
Loading Zephyr default modules (Zephyr base (cached)).
....
$ cat build/zephyr/.config |grep LLVM_USE
CONFIG_LLVM_USE_LD=y
# CONFIG_LLVM_USE_LLD is not set

As you see, touching .config will cause a CMake re-run which triggers a kconfig run that ensures all choices has a value.

Could someone really add an extra KConfig option without editing this code?

You can extend choices with new entries downstream, for example like it's done here:
https://github.com/nrfconnect/sdk-nrf/blob/5f58fc4ae964e24e5b432bcfcca865f857286f62/Kconfig.nrf#L23-L38
where the Zephyr provided options for an mbedTLS implementation is extended with an extra choice entry in a downstream project.

Can this FATAL_ERROR really cause invalid .config files to be generated?

No, but a FATAL_ERROR in CMake will prevent running menuconfig, cause the build file (which contains the menuconfig build target) has never been created.

Therefore, mis-configured Kconfig files should not result in fatal errors in CMake cause users will not be able to open menuconfig to fix the error.

So in this case, there is no value in throwing an error that a user cannot fix.
Plus it prevents downstream projects to provide extra choice options, and that's making it harder to extend Zephyr on a general basis.

In this particular case, there is probably little risk, but users will copy this pattern else-where, not realizing the damage / limitations it may introduce at other places.

Comment thread cmake/modules/FindGnuLd.cmake Outdated
Comment thread cmake/modules/FindGnuLd.cmake Outdated
Comment thread cmake/modules/FindLlvmLld.cmake Outdated
Comment thread cmake/modules/FindLlvmLld.cmake Outdated
Comment thread cmake/toolchain/llvm/target.cmake Outdated
Comment on lines 12 to 14
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the reason for the split in generic.cmake and target.cmake, so no reason for such comment.

Suggested change
# Since kconfigs are not available when generic.cmake
# is parsed. Setting the target triple for x86 needs to
# be done here instead.

Copy link
Copy Markdown
Contributor

@marc-hb marc-hb Mar 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the reason for the split in generic.cmake and target.cmake, so no reason for such comment.

OK but how many other people can easily understand that besides yourself + 1 or 2 others in the entire world? I know it's very hard but please try to put yourself in the shoes of non domain experts. I do NOT have the answer, this is a genuine question, not a rhetorical question. I do not have the answer but if @dcpleung who just spent weeks working on this PR - which makes him much, much more expert than the average - felt the need for this comment then I would tend to trust him that it is useful. Also: how does it hurt? It's only 3 lines and very far from a CMake crash course.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this but kept the comment on setting LINKER in generic.cmake, where it mentioned about kconfig not being available during parsing of generic.cmake.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK but how many other people can easily understand that besides yourself + 1 or 2 others in the entire world?

Then the comment should be the purpose of the generic.cmake / target.cmake files, and not why the triple (in this file) or why setting the linker is deferred to target.cmake (comment in the generic file).

I would be in favor of general comments in top of the file, for example like this:

+++ b/cmake/toolchain/<toolchain>/generic.cmake
@@ -1,5 +1,9 @@
 # SPDX-License-Identifier: Apache-2.0
 
+# Purpose of the generic.cmake is to define a generic C compiler which can be
+# used for devicetree pre-processing and other pre-processing tasks which must
+# be performed before the target can be determined.
+

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this and removed the other comments.

Comment thread cmake/toolchain/llvm/generic.cmake Outdated
Comment thread cmake/linker/ld/target.cmake Outdated
Comment on lines 11 to 12
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this looks as a very fragile test.

Could we do this another / cleaner way ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could change it to test if arch is posix and CONFIG_LLVM_USE_LD is enabled. I have only see it for native_posix as llvm links crt{being,end}S.o automatically. Let me try that.

This comment was marked as outdated.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this to test if LIBGCC_DIR is defined. Since posix arch does not have it, it skips including crtbegin.o and crtend.o.

Comment thread cmake/modules/FindGnuLd.cmake Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a bit stricter?

Suggested change
"GNU ld \\(.+\\) ([0-9]+[.][0-9]+[.]?[0-9]*).*"
"GNU ld \\(.+\\) ([0-9]+[.][0-9]+[.]?[0-9]*)$"

What happens when there's no match? Did you locally break the regex and see how that's reported?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version string would simply be empty. Cmake will not print the version, and any version comparisons will be false.

Comment thread cmake/toolchain/llvm/target.cmake Outdated
Comment on lines 7 to 9
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really needed ? A choice will always have a value,...

Unless when editing the .config file manually or generating from fragments and some non-Zephyr script?

so the only way that both CONFIG_LLVM_USE_LD and CONFIG_LLVM_USE_LLD could n is in case someone extended the choice with an extra config option.

Could someone really add an extra KConfig option without editing this code?

Finally, fatal errors should be used with absolute caution when it comes to Kconfig settings because of #9573

I only skimmed 9573 sorry but the main message seems to be "don't generate invalid .config files that menuconfig" can't read again. It will of course always be possible to make invalid .config edits manually.

Can this FATAL_ERROR really cause invalid .config files to be generated?

In my experience CMake and Kconfig errors tend to be a nightmare to debug + no one wants to go anywhere near them. Very understandable when you look at major design mistakes like COMMAND_ERROR_IS_FATAL false by default, MYPROGRAM_NOT-FOUND and other crazy and super time-consuming CMake stuff like https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/

So in general we need MORE user-friendly error messages, not fewer but maybe this particular case is different? Not convinced of that yet.

Comment thread cmake/toolchain/llvm/target.cmake Outdated
Comment on lines 12 to 14
Copy link
Copy Markdown
Contributor

@marc-hb marc-hb Mar 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the reason for the split in generic.cmake and target.cmake, so no reason for such comment.

OK but how many other people can easily understand that besides yourself + 1 or 2 others in the entire world? I know it's very hard but please try to put yourself in the shoes of non domain experts. I do NOT have the answer, this is a genuine question, not a rhetorical question. I do not have the answer but if @dcpleung who just spent weeks working on this PR - which makes him much, much more expert than the average - felt the need for this comment then I would tend to trust him that it is useful. Also: how does it hurt? It's only 3 lines and very far from a CMake crash course.

Comment thread cmake/toolchain/llvm/Kconfig Outdated
Some distros may provide config files for clang to change its
default behavior. We need to override that, or else developers
may be using different defaults and we will have confusing
bug reports in the future.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
@dcpleung dcpleung force-pushed the linker/no_pie_native_posix_only branch 2 times, most recently from 2e11342 to 2759602 Compare March 2, 2023 21:53
Copy link
Copy Markdown
Contributor

@tejlmand tejlmand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

A minor concern to reply to before a +1

Comment thread cmake/modules/FindGnuLd.cmake Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that always true, or just true 99% of the time ?
If we start reporting this, then we should really be sure that it's correct.

In linux, there will almost always an ld.bfd and ld will usually be a link to the ld.bfd exe.
The almost is to take into account any obscure distro / home built toolchain where ld could be an ld.bfd without ld.bfd existing (or not in path).

But what about other OS'es and pre-built cross tool-chains ?
Are we sure all conforms to the <triple>-ld.bfd or could some be lazy and provide only <triple>-ld, for example on Windows where links (the unix way) are not supported.
Such that <triple>-ld.exe is in fact a bfd.

I agree that most likely your assumption is correct, but worried about edge-cases.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more of a case where we can be certain that the linker is bfd compatible. We do ask the compilers for their preferred ld.bfd binary, and if they say there is one, we assume it is bfd compatible. This is simply a case where if we have any doubts, assume the linker is not bfd compatible.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accepted

tejlmand
tejlmand previously approved these changes Mar 17, 2023
@dcpleung
Copy link
Copy Markdown
Member Author

Compliance failure is due to the kconfig file being selectively included (based on which toolchain being used), and thus any documentation on those kconfigs generated check errors as clang is not used by default (and thus not the checked).

dcpleung added 11 commits March 29, 2023 14:59
This moves CONFIG_LLVM_USE_LD into cmake/toolchain/llvm as this
is a toolchain kconfig. Also make it a choice to allow the use
of LLVM's lld as linker.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This introduces a new cmake module FindGnuLd.cmake to do
the work to discover GNU ld (of binutils).

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This introduces a new cmake module FindLlvmLld.cmake to do
the work to discover LLVM lld linker.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
The variable LINKER is dependent on CONFIG_LLVM_USE_LLD
or CONFIG_LLVM_USE_LD, and these kconfigs are not
available when toolchain/llvm/generic.cmake is parsed.
So setting LINKER needs to be deferred to target.cmake
where kconfigs are available.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This asks the compiler if it has its own preference for ld.bfd.
This is useful for LLVM (when CONFIG_LLVM_USE_LD=y) so we know
which linker clang is using.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This asks the clang if it has its own preference for ld.lld.
This is to mirror what we are doing to find GNU ld, and to
make sure we are using the linker clang is using.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Since kconfigs are not available when generic.cmake is parsed.
Setting the target triple for x86 needs to be deferred to
target.cmake as it needs to know whether CONFIG_64BIT is
enabled. This also moves the ARM triple to target.cmake as
triple is needed for target tools.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This adds a new output variable to FindGnuLd.cmake to indicate
if ld.bfd is found. Since we now ask the compilers for their
preferred ld.bfd linker, it may not match using the existing
string equal test to ${CROSS_COMPILE}ld.bfd. So set the new
variable GNULD_LINKER_IS_BFD to true if ld.bfd, and use it to
pass an extra argument to compiler to make it use ld.bfd.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This adds a new linker property specifically for passing
"-no-pie" to linker. Older binutils' LD (<= 2.36) do not
support this flag and will behave erratically if set. It
would parse "-no-pie" separately as "-n" and "-o-pie",
which would result in the output file being "-pie"
instead of "zephyr*.elf". Moreover, LLVM lld does not
support -no-pie but --no-pie (note the extra hyphen).
By having no-pie as a linker property, we can pass
correct no-pie flag to these linkers (or none at all).

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
GNU ld and LLVM lld both complain under C++:
  error: section: init_array is not contiguous with other relro sections

So do not create RELRO program header.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Only include crtbegin.o and crtend.o when LIBGCC_DIR is defined.
Since LIBGCC_DIR is not defined when compiling for posix
architecture, crt{begin,end}.o cannot be referred to via
LIBGCC_DIR.

Also note that, when using llvm/clang, crt{begin,end}S.o are
automatically for native_posix which collide with symbols in
crt{begin,end}.o. So there is no point in making LIBGCC_DIR
available for native_posix under llvm/clang.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
@dcpleung dcpleung force-pushed the linker/no_pie_native_posix_only branch from 2759602 to 9a8acac Compare March 29, 2023 22:00
@dcpleung dcpleung requested a review from carlescufi as a code owner March 29, 2023 22:00
@dcpleung
Copy link
Copy Markdown
Member Author

The last change was simply adding the kconfigs to the compliance check ignore list.

@nashif nashif merged commit c9d70bb into zephyrproject-rtos:main Mar 29, 2023
@dcpleung dcpleung deleted the linker/no_pie_native_posix_only branch March 30, 2023 03:28
@marc-hb
Copy link
Copy Markdown
Contributor

marc-hb commented Apr 4, 2023

In some conditions, the commit that adds GNULD_LINKER_IS_BFD causes very confusing "-fuse-ld=bfd: unknown flag failures:

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.