Skip to content

IRGen: Always use symbolic references in mangled names (on Mach-O platforms) #27467

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/swift/Reflection/ReflectionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ class ReflectionContext
auto SecBuf = this->getReader().readBytes(
RemoteAddress(SectionHdrAddress + (I * SectionEntrySize)),
SectionEntrySize);
if (!SecBuf)
return false;
auto SecHdr =
reinterpret_cast<const typename T::Section *>(SecBuf.get());
SecHdrVec.push_back(SecHdr);
Expand Down
12 changes: 4 additions & 8 deletions include/swift/Reflection/TypeRefBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,8 @@ class TypeRefBuilder {
// Try to resolve to the underlying type, if we can.
if (opaqueDescriptor->getKind() ==
Node::Kind::OpaqueTypeDescriptorSymbolicReference) {
if (!OpaqueUnderlyingTypeReader)
return nullptr;

auto underlyingTy = OpaqueUnderlyingTypeReader(
(const void *)opaqueDescriptor->getIndex(), ordinal);
opaqueDescriptor->getIndex(), ordinal);

if (!underlyingTy)
return nullptr;
Expand Down Expand Up @@ -598,7 +595,7 @@ class TypeRefBuilder {
unsigned PointerSize;
std::function<Demangle::Node * (RemoteRef<char>)>
TypeRefDemangler;
std::function<const TypeRef* (const void*, unsigned)>
std::function<const TypeRef* (uint64_t, unsigned)>
OpaqueUnderlyingTypeReader;

public:
Expand All @@ -613,9 +610,8 @@ class TypeRefBuilder {
Dem, /*useOpaqueTypeSymbolicReferences*/ true);
}),
OpaqueUnderlyingTypeReader(
[&reader](const void *descriptor, unsigned ordinal) -> const TypeRef* {
auto context = (typename Runtime::StoredPointer)descriptor;
return reader.readUnderlyingTypeForOpaqueTypeDescriptor(context,
[&reader](uint64_t descriptorAddr, unsigned ordinal) -> const TypeRef* {
return reader.readUnderlyingTypeForOpaqueTypeDescriptor(descriptorAddr,
ordinal);
})
{}
Expand Down
9 changes: 7 additions & 2 deletions include/swift/Remote/CMemoryReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,13 @@ class CMemoryReader final : public MemoryReader {

bool readString(RemoteAddress address, std::string &dest) override {
auto length = getStringLength(address);
if (!length)
return false;
if (length == 0) {
// A length of zero unfortunately might mean either that there's a zero
// length string at the location we're trying to read, or that reading
// failed. We can do a one-byte read to tell them apart.
auto buf = readBytes(address, 1);
return buf && ((const char*)buf.get())[0] == 0;
}

auto Buf = readBytes(address, length);
if (!Buf)
Expand Down
2 changes: 1 addition & 1 deletion lib/Basic/QuotedString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void swift::printAsQuotedString(llvm::raw_ostream &out, llvm::StringRef text) {
};
out << "\\u{" << hexdigit[c >> 4] << hexdigit[c & 0xF] << '}';
} else {
out << c;
out << (char)c;
}
break;
}
Expand Down
1 change: 1 addition & 0 deletions lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ Node::iterator Node::end() const {
}

void Node::addChild(NodePointer Child, NodeFactory &Factory) {
assert(Child);
switch (NodePayloadKind) {
case PayloadKind::None:
InlineChildren[0] = Child;
Expand Down
51 changes: 34 additions & 17 deletions lib/IRGen/IRGenMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,26 +93,43 @@ IRGenMangler::withSymbolicReferences(IRGenModule &IGM,
AllowSymbolicReferences = true;
CanSymbolicReference = [&IGM](SymbolicReferent s) -> bool {
if (auto type = s.dyn_cast<const NominalTypeDecl *>()) {
// FIXME: Sometimes we fail to emit metadata for Clang imported types
// even after noting use of their type descriptor or metadata. Work
// around by not symbolic-referencing imported types for now.
if (type->hasClangNode())
return false;

// TODO: We ought to be able to use indirect symbolic references even
// when the referent may be in another file, once the on-disk
// ObjectMemoryReader can handle them.
// Private entities are known to be accessible.
auto formalAccessScope = type->getFormalAccessScope(nullptr, true);
if ((formalAccessScope.isPublic() || formalAccessScope.isInternal()) &&
(!IGM.CurSourceFile ||
IGM.CurSourceFile != type->getParentSourceFile()))
// The short-substitution types in the standard library have compact
// manglings already, and the runtime ought to have a lookup table for
// them. Symbolic referencing would be wasteful.
if (type->getModuleContext()->isStdlibModule()
&& Mangle::getStandardTypeSubst(type->getName().str())) {
return false;
}

// @objc protocols don't have descriptors.
if (auto proto = dyn_cast<ProtocolDecl>(type))
if (proto->isObjC())
// TODO: We could assign a symbolic reference discriminator to refer
// to objc protocol refs.
if (auto proto = dyn_cast<ProtocolDecl>(type)) {
if (proto->isObjC()) {
return false;
}
}

// Classes defined in Objective-C don't have descriptors.
// TODO: We could assign a symbolic reference discriminator to refer
// to objc class refs.
if (auto clas = dyn_cast<ClassDecl>(type)) {
if (clas->hasClangNode()
&& clas->getForeignClassKind() != ClassDecl::ForeignKind::CFType) {
return false;
}
}

// TODO: ObjectMemoryReader for ELF and PE platforms still does not
// implement symbol relocations. For now, on non-Mach-O platforms,
// only symbolic reference things in the same module.
if (IGM.TargetInfo.OutputObjectFormat != llvm::Triple::MachO) {
auto formalAccessScope = type->getFormalAccessScope(nullptr, true);
if ((formalAccessScope.isPublic() || formalAccessScope.isInternal()) &&
(!IGM.CurSourceFile ||
IGM.CurSourceFile != type->getParentSourceFile())) {
return false;
}
}

return true;
} else if (auto opaque = s.dyn_cast<const OpaqueTypeDecl *>()) {
Expand Down
8 changes: 4 additions & 4 deletions test/IRGen/access_type_metadata_by_mangled_name.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

// CHECK: @"$s36access_type_metadata_by_mangled_name3FooCyAA3BarCyAA3ZimCyAA4ZangCGGGMD" = linkonce_odr hidden global { i32, i32 }

// CHECK-little-SAME: @"symbolic 36access_type_metadata_by_mangled_name3FooCyAA3BarCyAA3ZimCyAA4ZangCGGG"
// CHECK-little-SAME: i32 -71
// CHECK-little-SAME: @"symbolic{{.*}}36access_type_metadata_by_mangled_name3FooC{{.*}}AA3BarC{{.*}}AA3ZimC{{.*}}AA4ZangC{{.*}}"
// CHECK-little-SAME: i32 -{{[0-9]+}}

// CHECK-big-SAME: i32 -71
// CHECK-big-SAME: @"symbolic 36access_type_metadata_by_mangled_name3FooCyAA3BarCyAA3ZimCyAA4ZangCGGG"
// CHECK-big-SAME: i32 -{{[0-9]+}}
// CHECK-big-SAME: @"symbolic{{.*}}36access_type_metadata_by_mangled_name3FooC{{.*}}AA3BarC{{.*}}AA3ZimCyAA4ZangC{{.*}}"

// CHECK-SAME: align 8

Expand Down
6 changes: 3 additions & 3 deletions test/IRGen/associated_type_witness.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protocol HasThreeAssocTypes {
// GLOBAL-SAME: @"$s23associated_type_witness13WithUniversalVAA8AssockedAAMc"
// GLOBAL-SAME: @"associated conformance 23associated_type_witness13WithUniversalVAA8AssockedAA5AssocAaDP_AA1P",
// GLOBAL-SAME: @"associated conformance 23associated_type_witness13WithUniversalVAA8AssockedAA5AssocAaDP_AA1Q"
// GLOBAL-SAME: i64 add (i64 ptrtoint (<{ [36 x i8], i8 }>* @"symbolic 23associated_type_witness9UniversalV" to i64), i64 1) to i8*)
// GLOBAL-SAME: i64 add (i64 ptrtoint (<{ {{.*}} }>* @"symbolic{{.*}}23associated_type_witness9UniversalV" to i64), i64 1) to i8*)
// GLOBAL-SAME: ]
struct WithUniversal : Assocked {
typealias Assoc = Universal
Expand All @@ -52,7 +52,7 @@ struct WithUniversal : Assocked {
// GLOBAL-SAME: @"$s23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAAMc"
// GLOBAL-SAME: @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5Assoc_AA1P"
// GLOBAL-SAME: @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5Assoc_AA1Q"
// GLOBAL-SAME: @"symbolic 23associated_type_witness9UniversalV"
// GLOBAL-SAME: @"symbolic{{.*}}23associated_type_witness9UniversalV"
// GLOBAL-SAME: ]
struct GenericWithUniversal<T> : Assocked {
typealias Assoc = Universal
Expand Down Expand Up @@ -90,7 +90,7 @@ struct Pair<T, U> : P, Q {}
// GLOBAL-SAME: @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAAMc"
// GLOBAL-SAME: @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1P"
// GLOBAL-SAME: @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1Q"
// GLOBAL-SAME: @"symbolic 23associated_type_witness4PairVyxq_G"
// GLOBAL-SAME: @"symbolic{{.*}}23associated_type_witness4PairV{{.*}}"
// GLOBAL-SAME: ]

struct Computed<T, U> : Assocked {
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/class_update_callback_with_stub.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import resilient_objc_class
// -- field descriptor
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMF"
// -- superclass
// CHECK-SAME: @"symbolic 15resilient_class22ResilientOutsideParentC"
// CHECK-SAME: @"symbolic{{[^"]*}}15resilient_class22ResilientOutsideParentC"
// -- metadata bounds
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMo"
// -- extra class flags -- has Objective-C resilient class stub
Expand Down
14 changes: 7 additions & 7 deletions test/IRGen/keypaths.sil
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ sil_vtable C2 {}
// -- %a: S.x
// CHECK: [[KP_A:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]]* @keypath_once
// CHECK-SAME: @"symbolic 8keypaths1SV"
// CHECK-SAME: @"symbolic{{.*}}8keypaths1SV"
// CHECK-SAME: @"symbolic Si
// -- instantiable in-line, size 4
// CHECK-SAME: <i32 0x8000_0004>,
Expand All @@ -71,7 +71,7 @@ sil_vtable C2 {}
// -- %b: S.y
// CHECK: [[KP_B:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]]* @keypath_once
// CHECK-SAME: @"symbolic 8keypaths1SV
// CHECK-SAME: @"symbolic{{.*}}8keypaths1SV
// CHECK-SAME: @"symbolic SS
// -- instantiable in-line, size 4
// CHECK-SAME: <i32 0x8000_0004>,
Expand All @@ -82,8 +82,8 @@ sil_vtable C2 {}
// -- %c: S.z
// CHECK: [[KP_C:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]]* @keypath_once
// CHECK-SAME: @"symbolic 8keypaths1SV
// CHECK-SAME: @"symbolic 8keypaths1CC
// CHECK-SAME: @"symbolic{{.*}}8keypaths1SV
// CHECK-SAME: @"symbolic{{.*}}8keypaths1CC
// -- instantiable in-line, size 4
// CHECK-SAME: <i32 0x8000_0004>,
// -- offset of S.z, mutable
Expand Down Expand Up @@ -237,7 +237,7 @@ sil_vtable C2 {}
// CHECK: [[KP_I:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: i32 0
// CHECK-SAME: @"generic environment l"
// CHECK-SAME: @"symbolic 8keypaths3GenVyxxG"
// CHECK-SAME: @"symbolic{{[^"]*}}8keypaths3GenV{{[^"]*}}"
// CHECK-SAME: @"symbolic x"
// -- size 8
// CHECK-SAME: i32 8,
Expand All @@ -250,7 +250,7 @@ sil_vtable C2 {}
// CHECK: [[KP_J:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: i32 0
// CHECK-SAME: @"generic environment l"
// CHECK-SAME: @"symbolic 8keypaths3GenVyxxG"
// CHECK-SAME: @"symbolic{{[^"]*}}8keypaths3GenV{{[^"]*}}"
// CHECK-SAME: @"symbolic x"
// -- size 8
// CHECK-SAME: i32 8,
Expand Down Expand Up @@ -305,7 +305,7 @@ sil_vtable C2 {}
// -- %gcx: GC<T>.x
// CHECK: [[KP_GCX:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: @"generic environment l"
// CHECK-SAME: @"symbolic 8keypaths2GCCyxG"
// CHECK-SAME: @"symbolic{{[^"]*}}8keypaths2GCC{{[^"]*}}"
// CHECK-SAME: @"symbolic x"
// -- class with runtime-resolved offset, mutable
// CHECK-SAME: <i32 0x3fffffe>
Expand Down
6 changes: 3 additions & 3 deletions test/IRGen/nested_generics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ extension Container.Conformancy3: HasAssoc where T == Outer {
}

// CHECK-CONSTANTS-LABEL: @"$s15nested_generics9ContainerO12Conformancy3Vyx_GAA8HasAssocA2A5OuterORszrlWP" =
// CHECK-CONSTANTS-SAME: @"symbolic 15nested_generics5OuterO"
// CHECK-CONSTANTS-SAME: @"symbolic{{.*}}15nested_generics5OuterO"

// CHECK-CONSTANTS-LABEL: @"$s15nested_generics9ContainerO12Conformancy2Vyx_qd__GAA8HasAssocA2A5OuterORszrlWP" =
// CHECK-CONSTANTS-SAME: @"symbolic 15nested_generics5OuterO"
// CHECK-CONSTANTS-SAME: @"symbolic{{.*}}15nested_generics5OuterO"

// CHECK-CONSTANTS-LABEL: @"$s15nested_generics9ContainerO11ConformancyVyx_qd__GAA8HasAssocAAWP" =
// CHECK-CONSTANTS-SAME: @"symbolic 15nested_generics5OuterO"
// CHECK-CONSTANTS-SAME: @"symbolic{{.*}}15nested_generics5OuterO"
2 changes: 1 addition & 1 deletion test/IRGen/sil_witness_tables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct Conformer: Q, QQ {
// CHECK: ]
// CHECK: [[CONFORMER_P_WITNESS_TABLE]] = hidden global [5 x i8*] [
// CHECK: @"associated conformance 18sil_witness_tables9ConformerVAA1PAA5AssocAaDP_AA1A"
// CHECK: "symbolic 18sil_witness_tables14AssocConformerV"
// CHECK: "symbolic{{.*}}18sil_witness_tables14AssocConformerV"
// CHECK: i8* bitcast (void (%swift.type*, %swift.type*, i8**)* @"$s18sil_witness_tables9ConformerVAA1PA2aDP12staticMethod{{[_0-9a-zA-Z]*}}FZTW" to i8*),
// CHECK: i8* bitcast (void (%T18sil_witness_tables9ConformerV*, %swift.type*, i8**)* @"$s18sil_witness_tables9ConformerVAA1PA2aDP14instanceMethod{{[_0-9a-zA-Z]*}}FTW" to i8*)
// CHECK: ]
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/witness_table_indirect_conformances.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct Z: P2 {
// CHECK: @"$s35witness_table_indirect_conformances1WVAA2P3AAWP" = hidden global [5 x i8*] [
// CHECK-SAME: @"$s35witness_table_indirect_conformances1WVAA2P3AAMc"
// CHECK-SAME: @"associated conformance 35witness_table_indirect_conformances1WVAA2P3AA05AssocE0AaDP_AA2P2"
// CHECK-SAME: @"symbolic 35witness_table_indirect_conformances1ZV"
// CHECK-SAME: @"symbolic{{.*}}35witness_table_indirect_conformances1ZV"
// CHECK-SAME: i8* bitcast (void (%T35witness_table_indirect_conformances1ZV*, %T35witness_table_indirect_conformances1WV*, %swift.type*, i8**)* @"$s35witness_table_indirect_conformances1WVAA2P3A2aDP08getAssocE00gE0QzyFTW" to i8*)]
struct W: P3 {
typealias AssocP3 = Z
Expand Down
4 changes: 2 additions & 2 deletions test/IRGen/witness_table_objc_associated_type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct SB: B {
}
// CHECK-LABEL: @"$s34witness_table_objc_associated_type2SBVAA1BAAWP" = hidden global [4 x i8*] [
// CHECK: @"associated conformance 34witness_table_objc_associated_type2SBVAA1BAA2AAAaDP_AA1A"
// CHECK: @"symbolic 34witness_table_objc_associated_type2SAV"
// CHECK: @"symbolic{{.*}}34witness_table_objc_associated_type2SAV"
// CHECK: i8* bitcast {{.*}} @"$s34witness_table_objc_associated_type2SBVAA1BA2aDP3fooyyFTW"
// CHECK: ]

Expand All @@ -31,7 +31,7 @@ struct SO: C {
func foo() {}
}
// CHECK-LABEL: @"$s34witness_table_objc_associated_type2SOVAA1CAAWP" = hidden global [3 x i8*] [
// CHECK: @"symbolic 34witness_table_objc_associated_type2COC"
// CHECK: @"symbolic{{.*}}34witness_table_objc_associated_type2COC"
// CHECK: i8* bitcast {{.*}} @"$s34witness_table_objc_associated_type2SOVAA1CA2aDP3fooyyFTW"
// CHECK: ]

Expand Down
3 changes: 3 additions & 0 deletions test/Reflection/Inputs/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// a dummy main.swift we can use to build executables to test reflection on
// intentionally left blank

4 changes: 4 additions & 0 deletions test/Reflection/typeref_decoding.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// REQUIRES: no_asan
// RUN: %empty-directory(%t)

// RUN: %target-build-swift -Xfrontend -enable-anonymous-context-mangled-names %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift %S/Inputs/Extensions.swift %S/Inputs/Closures.swift -parse-as-library -emit-module -emit-library -module-name TypesToReflect -o %t/%target-library-name(TypesToReflect)
// RUN: %target-build-swift -Xfrontend -enable-anonymous-context-mangled-names %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift %S/Inputs/Extensions.swift %S/Inputs/Closures.swift %S/Inputs/main.swift -emit-module -emit-executable -module-name TypesToReflect -o %t/TypesToReflect

// RUN: %target-swift-reflection-dump -binary-filename %t/%target-library-name(TypesToReflect) | %FileCheck %s
// RUN: %target-swift-reflection-dump -binary-filename %t/TypesToReflect | %FileCheck %s

// CHECK: FIELDS:
// CHECK: =======
Expand Down
Loading