We need to dedup archive loads (similar to what we do for dylib
loads).
I noticed this issue after building some Swift stuff that used
-force_load_swift_libs, as it caused some Swift archives to be loaded
many times.
Differential D104353
[lld-macho] Avoid force-loading the same archive twice int3 on Jun 15 2021, 9:54 PM. Authored by
Details
We need to dedup archive loads (similar to what we do for dylib I noticed this issue after building some Swift stuff that used
Diff Detail
Event TimelineComment Actions (So ld64 -force_load behaves similar to link.exe -wholearchive: where input filenames are (unfortunately) deduplicated. I like the ELF --whole-archive no-magic version...)
Comment Actions (I agree with MaskRay that the ELF behavior is nicer, but you solve the problems you have, not the ones you wish you had.)
Comment Actions Also, have you checked how symlinks/hardlinks behave? lld-link uses sys::fs::getUniqueID. Comment Actions Yeah as mentioned in my inline comment, my experiments show that ld64 treats symlinks as distinct inputs. But @thakis seems to think its otherwise, so we'll see... If symlinks are distinct, then hardlinks should be distinct too, and that seems to hold up. I'll update the diff to show my test cases, which pass both with LLD and ld64.
Comment Actions remove use of ln; add test for force-loading multiple non-conflicting archives, and a test for non-force-loading multiple conflicting archives
Comment Actions Looks like this breaks tests on some windows bots: https://logs.chromium.org/logs/chromium/buildbucket/cr-buildbucket.appspot.com/8844046562894240432/+/u/package_clang/stdout?format=raw $ ":" "RUN: at line 19" $ "ld64.lld" "-arch" "x86_64" "-platform_version" "macos" "10.15" "11.0" "-syslibroot" "C:/b/s/w/ir/cache/builder/src/third_party/llvm/lld/test\MachO\Inputs\MacOSX.sdk" "-fatal_warnings" "-lSystem" "C:\b\s\w\ir\cache\builder\src\third_party\llvm-bootstrap\tools\lld\test\MachO\Output\force-load.s.tmp/foo.o" "-force_load" "C:\b\s\w\ir\cache\builder\src\third_party\llvm-bootstrap\tools\lld\test\MachO\Output\force-load.s.tmp/foo.a" "-force_load" "C:\b\s\w\ir\cache\builder\src\third_party\llvm-bootstrap\tools\lld\test\MachO\Output\force-load.s.tmp/foo.a" "C:\b\s\w\ir\cache\builder\src\third_party\llvm-bootstrap\tools\lld\test\MachO\Output\force-load.s.tmp/test.o" "-o" "/dev/null" # command stderr: ld64.lld: error: duplicate symbol: _bar >>> defined in C:\b\s\w\ir\cache\builder\src\third_party\llvm-bootstrap\tools\lld\test\MachO\Output\force-load.s.tmp/foo.a(archive-foo.o) >>> defined in C:\b\s\w\ir\cache\builder\src\third_party\llvm-bootstrap\tools\lld\test\MachO\Output\force-load.s.tmp/foo.a(archive-foo.o) Comment Actions Hm, but that didn't happen in our nightly build last night. So I guess something else broke the test since then?
Comment Actions The real culprit is https://github.com/llvm/llvm-project/commit/1d31fb8d122b1117cf20a9edc09812db8472e930, which I (unfortunately) thought simple enough to be landed without review. And I only landed it today, which explains why the breakage only happened today. The issue is that it made rerootPath return a temporary std::string instead of an interned string, which then gets passed to addFile as a StringRef, so it gets prematurely freed. I'll back out the std::string change and re-land this force-load diff.
|
I don't know if that's what's happening, but if loadArchiveMember() loads a .o file that contains LC_LINKER_OPTIONS that has a -l flag that can recursively call addFile() again which can resize loadedArchives and invalidate the cachedFile ref.