PR:52564
Details
- Reviewers
int3 thevinster - Group Reviewers
Restricted Project - Commits
- rG74cbd71072de: [lld-macho] Mark dylib symbols coming from -weak_framework as weak-ref.
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Sorry - forgot the --draft when running arc diff
Anyway, should be ready to review now :) (With tests! )
lld/test/MachO/weak-import.s | ||
---|---|---|
13–18 | This is just renaming the output %t/test to different names so we don't overwrite the binaries. (makes it easier for debugging/examining the outputs afterwards) |
Probably should look at the failing tests. Seems to be related to your changes. [EDIT] - looks like it's fixed but my comment below still stands.
lld/MachO/Driver.cpp | ||
---|---|---|
391 | Hmm.... I'm not sure why this change is needed? I think the original code of forcefully setting forceWeakImport on the dylibFile should be fine. I think the only change missing here is the change in isWeakDef and isWeakRef to make sure it accounts for the forceWeakImport flag which you already did in Symbols.h. Everything else can stay as is. |
lld/MachO/Driver.cpp | ||
---|---|---|
391 | There were two problems:
So the change here is to ensure we propagate the flag to loadDylib |
lld/MachO/Driver.cpp | ||
---|---|---|
391 | Ooh, I see what you're saying. Yes - you're right :P Sorry wasn't reading carefully |
lld/MachO/SymbolTable.cpp | ||
---|---|---|
170 | Hmm... I still don't understand why this change is needed. This code never gets run after the first framework gets loaded because it would short circuit and return the cached file (https://github.com/llvm/llvm-project/blob/main/lld/MachO/DriverUtils.cpp#L212). I think the -weak_framework is just meant to set the the forceWeakImport flag which is being accounted for in Symbols.h. I pulled the diff in, removed all the changes in SymbolTable and only kept Symbols.h changes, and the test still passed. |
lld/MachO/SymbolTable.cpp | ||
---|---|---|
170 | hmmm .... Didn't work for me . (or rather this was needed to fix the missing symbol crash at runtime ) |
lld/MachO/SymbolTable.cpp | ||
---|---|---|
170 | P.S : ignore that - PEBCAK |
Catching up on this now... is this part of the commit message still accurate?
if a framework was previoulsy loaded as regular, then it was loaded again as weak, then the weak flag would not be propagated
also
Symbols imported from weak framework should be marked as weak-def.
The test is only checking that they are marked as weak *refs*, though :) are the changes to isWeakDef necessary?
Otherwise, we may get runtime crash due to symbols not found.
Would be good to add this as an explanatory comment to isWeakRef.
lld/MachO/Symbols.h | ||
---|---|---|
243 | we can cast<> here, there's no doubt about what the underlying type is (and if it's wrong the current code would do a null deref anyway) | |
243 | I think we may need to make this getFile()->umbrella here to ensure symbols in re-exports are handled correctly too. (should add a test for that too) | |
lld/test/MachO/weak-import.s | ||
14 | nit: the other filenames use hyphens instead of underscores, let's stick with that also I assume here "core" means "CoreFoundation"? I think "cf" would be clearer... but also I don't think it is a super accurate name for this test 🤔since here we are testing 3 different weak-import flags, only one of which applies to CF. IMO we can just call this test %t/basic, since, well, that's what it is as far as weak-import flags are concerned | |
17 | %t/test-strong-weak? | |
25–26 | imo there's no need to create two additional binaries here; we can just reuse the binaries created in lines 16 and 17 above |
Yes ... (ish)
if a framework was previoulsy loaded as regular, then it was loaded again as weak, then the weak flag would not be propagated
also
Symbols imported from weak framework should be marked as weak-def.
The test is only checking that they are marked as weak *refs*, though :) are the changes to isWeakDef necessary?
Ok agreed that the test is only for refs - but logically speaking it should apply to def too
Otherwise, we may get runtime crash due to symbols not found.
Would be good to add this as an explanatory comment to isWeakRef.
done
lld/test/MachO/weak-import.s | ||
---|---|---|
25–26 | 25 can be used with 16 - yes. |
Yes ... (ish)
Can you explain why you think "the implementation did not do that"? Lines 12 and 13 in the old test (before your changes) cover that case...
but logically speaking it should apply to def too
I'm not sure it follows logically. Did you see ld64 doing this too? Weak reference => a missing symbol at runtime is not an error. Weak definition => duplicate symbols at runtime is not an error. The former is definitely relevant for weak libraries, but I don't see how the latter comes in.
Would be good to add this as an explanatory comment to isWeakRef.
done
I don't see it, did you forget to update the diff? I also don't see a test for a re-exported symbol :)
lld/test/MachO/weak-import.s | ||
---|---|---|
25–26 | 16 tests strong-weak-strong, so it technically encompasses both strong-weak and weak-strong :p or at the very least it shows that weakness takes precedence over strong regardless of flag order. I'm fine if you would like to break it up into two binaries, strong-weak and weak-strong, but we can def reuse it |
Let me try responding again with more thinking
( Wed was sort of holiday-eve so I was in a rush... sorry about that)
What I said was mainly on the handling of the symbols from weak libraries/frameworks.
IOWs, line 12-13 (in the old tests) only tested that the weak things had proper load-commands (LC_LOAD_WEAK_DYLIB vs LC_LOAD_DYLIB) but nothing on the semantic of the symbols in them. (hence this bug :) )
but logically speaking it should apply to def too
I'm not sure it follows logically.
Consider this test:
-arch x86_64 -platform_version macos 10.15 11.0 -syslibroot <path>lld/test/MachO/Inputs/MacOSX.sdk -weak_framework NewCoreFoundation -framework CoreFoundation test.o
(Imagine NewCoreFoundation is just a duplicate of CoreFoundation with the same symbols defined)
Which __CFBigNumGetInt128 do you think should be picked?
IMO, since the NewCoreFoundation is weak, the symbols should come from the non-weak one, ie CoreFoundation.
Did you see ld64 doing this too? Weak reference => a missing symbol at runtime is not an error. Weak definition => duplicate symbols at runtime is not an error. The former is definitely relevant for weak libraries, but I don't see how the latter comes in.
No - it doesn't do this - it just picks whichever comes first on the link-command.
Having said that, if you all think we should mimic LD64 here - i'm happy to revert the change in isWeakDef() - Just wanted to bring this up
Would be good to add this as an explanatory comment to isWeakRef.
done
I don't see it, did you forget to update the diff? I also don't see a test for a re-exported symbol :)
done (real)
What I said was mainly on the handling of the symbols from weak libraries/frameworks.
Right, so there are two parts to your commit message...
Symbols imported from weak framework should be marked as weak-def. Otherwise, we may get runtime crash due to symbols not found.
This part is what your diff fixes
Additionally, frameworks/libraries can be specified multiple times (eg. -framework Foo -weak_frameworks Foo). When that happens,
the "forceWeakImport" should be "contagious"
This is already existing behavior
IMO, since the NewCoreFoundation is weak, the symbols should come from the non-weak one, ie CoreFoundation.
"weak" is an (unfortunately) overloaded term here. From reading ld64's manpage, it seems that "weak library" is just short for "weakly referenced library". There's nothing there that says that they contain weak definitions as well.
And in the future please highlight any intentional deviations from ld64's behavior in the commit message :)
done (real)
Explanatory comment is done, but we still need a test involving a re-exported symbol
lld/MachO/Symbols.h | ||
---|---|---|
239 | ||
242–243 | not really sure this comment is important -- we don't actually call isWeakRef until after all the file parsing is done anyway. Also the computation involved is pretty trivial, I don't think we'd ever consider it as a candidate for caching |
Ok, understood. Since it's now undocumented territory, do you 👎 or 👍 the weak-def change?
And in the future please highlight any intentional deviations from ld64's behavior in the commit message :)
updated
done (real)
Explanatory comment is done, but we still need a test involving a re-exported symbol
Hmm.... I'm not sure why this change is needed? I think the original code of forcefully setting forceWeakImport on the dylibFile should be fine. I think the only change missing here is the change in isWeakDef and isWeakRef to make sure it accounts for the forceWeakImport flag which you already did in Symbols.h. Everything else can stay as is.