Skip to content

Commit e1f92cc

Browse files
committed
Add a -force-public-linkage IRGen flag for LLDB.
In LLDB expressions, references to private metadata accessors may be emitted and need to be bound to symbols available in the attached program, even if these symbols are only supposed to have private visibility within the program. Also rdar://problem/48018240
1 parent 65d4199 commit e1f92cc

File tree

9 files changed

+71
-3
lines changed

9 files changed

+71
-3
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ class IRGenOptions {
168168
/// Emit mangled names of anonymous context descriptors.
169169
unsigned EnableAnonymousContextMangledNames : 1;
170170

171+
/// Force public linkage for private symbols. Used only by the LLDB
172+
/// expression evaluator.
173+
unsigned ForcePublicLinkage : 1;
174+
171175
/// Bypass resilience when accessing resilient frameworks.
172176
unsigned EnableResilienceBypass : 1;
173177

@@ -234,6 +238,7 @@ class IRGenOptions {
234238
EmbedMode(IRGenEmbedMode::None), HasValueNamesSetting(false),
235239
ValueNames(false), EnableReflectionMetadata(true),
236240
EnableReflectionNames(true), EnableAnonymousContextMangledNames(false),
241+
ForcePublicLinkage(false),
237242
EnableResilienceBypass(false), LazyInitializeClassMetadata(false),
238243
LazyInitializeProtocolConformances(false), DisableLegacyTypeInfo(false),
239244
UseIncrementalLLVMCodeGen(true), UseSwiftCall(false),

include/swift/IRGen/Linking.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,16 @@ class UniversalLinkageInfo {
4949
/// True iff are multiple llvm modules.
5050
bool HasMultipleIGMs;
5151

52+
/// When this is true, the linkage for forward-declared private symbols will
53+
/// be promoted to public external. Used by the LLDB expression evaluator.
54+
bool ForcePublicDecls;
55+
5256
bool IsWholeModule;
5357

5458
explicit UniversalLinkageInfo(IRGenModule &IGM);
5559

5660
UniversalLinkageInfo(const llvm::Triple &triple, bool hasMultipleIGMs,
57-
bool isWholeModule);
61+
bool forcePublicDecls, bool isWholeModule);
5862

5963
/// In case of multiple llvm modules (in multi-threaded compilation) all
6064
/// private decls must be visible from other files.
@@ -66,6 +70,12 @@ class UniversalLinkageInfo {
6670
/// IRGen into different object files and the linker would complain about
6771
/// duplicate symbols.
6872
bool needLinkerToMergeDuplicateSymbols() const { return HasMultipleIGMs; }
73+
74+
/// This is used by the LLDB expression evaluator since an expression's
75+
/// llvm::Module may need to access private symbols defined in the
76+
/// expression's context. This flag ensures that private accessors are
77+
/// forward-declared as public external in the expression's module.
78+
bool forcePublicDecls() const { return ForcePublicDecls; }
6979
};
7080

7181
/// Selector for type metadata symbol kinds.

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,9 @@ def prebuilt_module_cache_path_EQ :
520520
def enable_resilience_bypass : Flag<["-"], "enable-resilience-bypass">,
521521
HelpText<"Completely bypass resilience when accessing types in resilient frameworks">;
522522

523+
def force_public_linkage : Flag<["-"], "force-public-linkage">,
524+
HelpText<"Force public linkage for private symbols. Used by LLDB.">;
525+
523526
def dump_api_path : Separate<["-"], "dump-api-path">,
524527
HelpText<"The path to output swift interface files for the compiled source files">;
525528

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,10 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
10851085
Opts.EnableResilienceBypass = true;
10861086
}
10871087

1088+
if (Args.hasArg(OPT_force_public_linkage)) {
1089+
Opts.ForcePublicLinkage = true;
1090+
}
1091+
10881092
// PE/COFF cannot deal with the cross-module reference to the metadata parent
10891093
// (e.g. NativeObject). Force the lazy initialization of the VWT always.
10901094
Opts.LazyInitializeClassMetadata = Triple.isOSBinFormatCOFF();

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,9 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
14621462
return RESULT(External, Hidden, Default);
14631463

14641464
case SILLinkage::Private: {
1465+
if (info.forcePublicDecls() && !isDefinition)
1466+
return getIRLinkage(info, SILLinkage::PublicExternal, isDefinition,
1467+
isWeakImported);
14651468
auto linkage = info.needLinkerToMergeDuplicateSymbols()
14661469
? llvm::GlobalValue::LinkOnceODRLinkage
14671470
: llvm::GlobalValue::InternalLinkage;

lib/IRGen/Linking.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "IRGenModule.h"
2020
#include "swift/AST/ASTMangler.h"
2121
#include "swift/AST/Availability.h"
22+
#include "swift/AST/IRGenOptions.h"
2223
#include "swift/ClangImporter/ClangModule.h"
2324
#include "swift/SIL/SILGlobalVariable.h"
2425
#include "swift/SIL/FormalLinkage.h"
@@ -68,14 +69,16 @@ bool swift::irgen::useDllStorage(const llvm::Triple &triple) {
6869

6970
UniversalLinkageInfo::UniversalLinkageInfo(IRGenModule &IGM)
7071
: UniversalLinkageInfo(IGM.Triple, IGM.IRGen.hasMultipleIGMs(),
72+
IGM.IRGen.Opts.ForcePublicLinkage,
7173
IGM.getSILModule().isWholeModule()) {}
7274

7375
UniversalLinkageInfo::UniversalLinkageInfo(const llvm::Triple &triple,
7476
bool hasMultipleIGMs,
77+
bool forcePublicDecls,
7578
bool isWholeModule)
7679
: IsELFObject(triple.isOSBinFormatELF()),
7780
UseDLLStorage(useDllStorage(triple)), HasMultipleIGMs(hasMultipleIGMs),
78-
IsWholeModule(isWholeModule) {}
81+
ForcePublicDecls(forcePublicDecls), IsWholeModule(isWholeModule) {}
7982

8083
/// Mangle this entity into the given buffer.
8184
void LinkEntity::mangle(SmallVectorImpl<char> &buffer) const {

lib/TBDGen/TBDGen.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,8 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
590590
auto &ctx = M->getASTContext();
591591
auto isWholeModule = singleFile == nullptr;
592592
const auto &target = ctx.LangOpts.Target;
593-
UniversalLinkageInfo linkInfo(target, opts.HasMultipleIGMs, isWholeModule);
593+
UniversalLinkageInfo linkInfo(target, opts.HasMultipleIGMs, false,
594+
isWholeModule);
594595
auto availCtx = AvailabilityContext::forDeploymentTarget(ctx);
595596

596597
tapi::internal::InterfaceFile file;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public struct S {
2+
public var a = 1
3+
4+
public init() {}
5+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend -emit-module -enable-library-evolution \
4+
// RUN: -emit-module-path=%t/lib.swiftmodule -module-name=lib \
5+
// RUN: -validate-tbd-against-ir=none \
6+
// RUN: %S/Inputs/force_public_metadata_accessors.swift
7+
// RUN: %target-swift-frontend -parse-as-library -enable-library-evolution \
8+
// RUN: -force-public-linkage \
9+
// RUN: -validate-tbd-against-ir=none -emit-ir %s -I %t | %FileCheck %s
10+
11+
import lib
12+
13+
private enum FixedContainer {
14+
case a(S)
15+
}
16+
17+
fileprivate var c = FixedContainer.a(S())
18+
public func use() -> Int {
19+
switch (c) {
20+
case let .a(s):
21+
return s.a
22+
}
23+
}
24+
25+
// CHECK: define {{.*}} @"$s31force_public_metadata_accessors3useSiyF"()
26+
// CHECK-NOT: define
27+
// CHECK: call {{.*}} %swift.metadata_response @"$s31force_public_metadata_accessors14FixedContainer{{.*}}LLOMa"
28+
29+
// FIXME: From within LLDB, this would be a forward declaration.
30+
// Unfortunately this is difficult to reproduce from source alone.
31+
// Really this should be a check for a non-internal "declare".
32+
// CHECK: define{{.*}} swiftcc %swift.metadata_response @"$s31force_public_metadata_accessors14FixedContainer{{.*}}LLOMa"
33+
34+

0 commit comments

Comments
 (0)