@@ -600,6 +600,29 @@ class ReflectionContext
600
600
return false ;
601
601
auto StrTab = reinterpret_cast <const char *>(StrTabBuf);
602
602
bool Error = false ;
603
+
604
+ // GNU ld and lld both merge sections regardless of the
605
+ // `SHF_GNU_RETAIN` flag. gold, presently, does not. The Swift
606
+ // compiler has a couple of switches that control whether or not
607
+ // the reflection sections are stripped; when these are enabled,
608
+ // it will _not_ set `SHF_GNU_RETAIN` on the reflection metadata
609
+ // sections. However, `swiftrt.o` contains declarations of the
610
+ // sections _with_ the `SHF_GNU_RETAIN` flag set, which makes
611
+ // sense since at runtime we will only expect to be able to access
612
+ // reflection metadata that we said we wanted to exist at runtime.
613
+ //
614
+ // The upshot is that when linking with gold, we can end up with
615
+ // two sets of reflection metadata sections. In a normal build
616
+ // where the compiler flags are the same for every linked object,
617
+ // we'll have *either* all retained *or* all un-retained sections
618
+ // (the retained sections will still exist because of `swiftrt.o`,
619
+ // but will be empty). The only time we'd expect to have a mix is
620
+ // where some code was compiled with a different setting of the
621
+ // metadata stripping flags. If that happens, the code below will
622
+ // simply add both sets of reflection sections, with the retained
623
+ // ones added first.
624
+ //
625
+ // See also https://sourceware.org/bugzilla/show_bug.cgi?id=31415.
603
626
auto findELFSectionByName =
604
627
[&](llvm::StringRef Name, bool Retained) -> std::pair<RemoteRef<void >, uint64_t > {
605
628
if (Error)
0 commit comments