This is an archive of the discontinued LLVM Phabricator instance.

[MC] Error for .globl/.local which change the symbol binding and warn for .weak
ClosedPublic

Authored by MaskRay on Oct 24 2020, 4:28 PM.

Details

Summary

GNU as let .weak override .globl since binutils-gdb
5ca547dc2399a0a5d9f20626d4bf5547c3ccfddd (1996) while MC lets the last
directive win (PR38921).

This caused an issue to Linux's powerpc port which has been fixed by
http://git.kernel.org/linus/968339fad422a58312f67718691b717dac45c399

Binding overriding is error-prone. This patch disallows a changed binding.
(https://sourceware.org/pipermail/binutils/2020-March/000299.html )

Our behavior regarding .globl x; .weak x matches GNU as. Such usage is
still suspicious but we issue a warning for now. We may upgrade it to an
error in the future.

Diff Detail

Event Timeline

MaskRay created this revision.Oct 24 2020, 4:28 PM
MaskRay requested review of this revision.Oct 24 2020, 4:28 PM

Personally I'd err on the side of consistency with binutils. If they are happy to go to an error then we can. If they aren't then I recommend that we warn rather than error as we risk breaking builds for working software and it isn't always easy to get source code fixed. Not got a strong opinion though so happy to go with the consensus.

nickdesaulniers accepted this revision.Oct 26 2020, 11:51 AM

I wonder how many Linux kernel targets will break when using LLVM_IAS=1 with this? We should be able to fix up any instances we find in kernel sources though. Thanks for the patch.

This revision is now accepted and ready to land.Oct 26 2020, 11:51 AM
MaskRay added a comment.EditedOct 26 2020, 2:31 PM

I wonder how many Linux kernel targets will break when using LLVM_IAS=1 with this? We should be able to fix up any instances we find in kernel sources though. Thanks for the patch.

ClangBuiltLinux/tc-build

cd kernel; ./build.sh -t X86 -s path/to/my/linux -p path/to/my/llvm/build/bin succeeds. There are probably not many.

Personally I'd err on the side of consistency with binutils. If they are happy to go to an error then we can. If they aren't then I recommend that we warn rather than error as we risk breaking builds for working software and it isn't always easy to get source code fixed. Not got a strong opinion though so happy to go with the consensus.

If we issue a warning instead, users will only notice the semantic difference when they use -Wa,--fatal-warnings. We can classify the potential risks on whether .local is used:

  • .local is used: .local is a very rare directive.
  • .local is not used: the issue is about .weak and .globl . This represents a semantic difference between MC and GNU ld. There may be a few more but I doubt there can be more than a few. Can we try error first and switch to a warning if it turns out to be a problem?

If we issue a warning instead, users will only notice the semantic difference when they use -Wa,--fatal-warnings. We can classify the potential risks on whether .local is used:

  • .local is used: .local is a very rare directive.
  • .local is not used: the issue is about .weak and .globl . This represents a semantic difference between MC and GNU ld. There may be a few more but I doubt there can be more than a few. Can we try error first and switch to a warning if it turns out to be a problem?

I don't object to go for an error; I do tend to be a bit nervous about making something an error that has been accepted for many years as contrary to my expectations that something is rare, there is almost always someone that has a special case and is greatly inconvenienced by it. If we are lucky very few people will be affected and they can change their code, if we are not then we may have to revisit.

If we issue a warning instead, users will only notice the semantic difference when they use -Wa,--fatal-warnings. We can classify the potential risks on whether .local is used:

  • .local is used: .local is a very rare directive.
  • .local is not used: the issue is about .weak and .globl . This represents a semantic difference between MC and GNU ld. There may be a few more but I doubt there can be more than a few. Can we try error first and switch to a warning if it turns out to be a problem?

I don't object to go for an error; I do tend to be a bit nervous about making something an error that has been accepted for many years as contrary to my expectations that something is rare, there is almost always someone that has a special case and is greatly inconvenienced by it. If we are lucky very few people will be affected and they can change their code, if we are not then we may have to revisit.

Thanks for the insight! This is something I have thought. .local is rare so this is about the semantic differences between .weak x;.globl x and .globl x;.weak x. Since we actually do different thing, and if the user's intention was to get a STB_WEAK, the current behavior may make them surprised. So an error is probably fine since we conjecture the number of instances is very few. We can surely loose it if it turns out to be a wide spreading problem.

We can surely loose it if it turns out to be a wide spreading problem.

The hard part is that regressions tend to get reported AFTER the release when it's too late to fix them. Maybe a warning for one release, then upgrade to hard error next release gives users more time to find and fix errors, and doesn't result in an unusable release version for anyone?

We can surely loose it if it turns out to be a wide spreading problem.

The hard part is that regressions tend to get reported AFTER the release when it's too late to fix them. Maybe a warning for one release, then upgrade to hard error next release gives users more time to find and fix errors, and doesn't result in an unusable release version for anyone?

We other kinds of diagnostics I might agree, for this particular one I think using a warning is a bit unnecessarily conservative.

We can surely loose it if it turns out to be a wide spreading problem.

The hard part is that regressions tend to get reported AFTER the release when it's too late to fix them. Maybe a warning for one release, then upgrade to hard error next release gives users more time to find and fix errors, and doesn't result in an unusable release version for anyone?

I don't have any specific evidence to suggest that we'd run into a problem doing this, but my personal thinking is that adding an option to allow disabling this error might be a good idea. I wouldn't be surprised to find code bases where fixing the code is non-trivial. Ideally, the option would not be made widely known unless actually asked for and/or heavily labelled with things saying something like "this is a temporary option that will be deleted in a future change unless a compelling reason is found not to".

We can surely loose it if it turns out to be a wide spreading problem.

The hard part is that regressions tend to get reported AFTER the release when it's too late to fix them. Maybe a warning for one release, then upgrade to hard error next release gives users more time to find and fix errors, and doesn't result in an unusable release version for anyone?

I don't have any specific evidence to suggest that we'd run into a problem doing this, but my personal thinking is that adding an option to allow disabling this error might be a good idea. I wouldn't be surprised to find code bases where fixing the code is non-trivial. Ideally, the option would not be made widely known unless actually asked for and/or heavily labelled with things saying something like "this is a temporary option that will be deleted in a future change unless a compelling reason is found not to".

If there are concerns, I can make .globl foo; .weak foo a warning instead of error. The others are still errors.

We can surely loose it if it turns out to be a wide spreading problem.

The hard part is that regressions tend to get reported AFTER the release when it's too late to fix them. Maybe a warning for one release, then upgrade to hard error next release gives users more time to find and fix errors, and doesn't result in an unusable release version for anyone?

I don't have any specific evidence to suggest that we'd run into a problem doing this, but my personal thinking is that adding an option to allow disabling this error might be a good idea. I wouldn't be surprised to find code bases where fixing the code is non-trivial. Ideally, the option would not be made widely known unless actually asked for and/or heavily labelled with things saying something like "this is a temporary option that will be deleted in a future change unless a compelling reason is found not to".

If there are concerns, I can make .globl foo; .weak foo a warning instead of error. The others are still errors.

I'm happy for that to be a warning, or an option to disable the error. As mentioned in the first comment, it is only a weakly held opinion.

MaskRay updated this revision to Diff 301425.Oct 28 2020, 2:06 PM
MaskRay edited the summary of this revision. (Show Details)

Use a warning if the binding is changed to STB_WEAK

MaskRay retitled this revision from [MC] Error for .weak/.globl/.local which change the symbol binding to [MC] Error for .globl/.local which change the symbol binding and warn for .weak.Oct 28 2020, 2:07 PM
nickdesaulniers accepted this revision.Oct 28 2020, 2:08 PM
jhenderson accepted this revision.Oct 29 2020, 1:51 AM

Looks good to me, with nits.

llvm/lib/MC/MCELFStreamer.cpp
230
240

(for consistency with the comment above)

MaskRay updated this revision to Diff 301644.Oct 29 2020, 9:03 AM
MaskRay marked an inline comment as done.

Comments

MaskRay marked an inline comment as done.Oct 29 2020, 9:03 AM
This revision was landed with ongoing or failed builds.Oct 29 2020, 9:08 AM
This revision was automatically updated to reflect the committed changes.