Skip to content

Commit

Permalink
Workaround dyld warning about SwiftSyntax classes (realm#4901)
Browse files Browse the repository at this point in the history
This uses a recent but unannounced (also read as private) feature of
dyld where it ignores duplicate Objective-C classes when they're in a
special format in the binary. https://github.com/apple-oss-distributions/dyld/blob/c8a445f88f9fc1713db34674e79b00e30723e79d/dyld/PrebuiltLoader.cpp#L1660-L1662

I think this is generally safe because hopefully people aren't actually
using the SwiftSyntax classes through the Objective-C runtime, but if
they are we'd still probably prefer to silence the noise and accept the
UB.

Fixes realm#4782
  • Loading branch information
keith authored Apr 17, 2023
1 parent 41290a2 commit 1892c84
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 3 deletions.
16 changes: 13 additions & 3 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ swift_library(
module_name = "SwiftLintFramework",
visibility = ["//visibility:public"],
deps = [
"@com_github_jpsim_sourcekitten//:SourceKittenFramework",
"@com_github_apple_swift_syntax//:optlibs",
"@com_github_jpsim_sourcekitten//:SourceKittenFramework",
"@sourcekitten_com_github_jpsim_yams//:Yams",
"@swiftlint_com_github_scottrhoyt_swifty_text_table//:SwiftyTextTable",
] + select({
"@platforms//os:linux": ["@com_github_krzyzanowskim_cryptoswift//:CryptoSwift"],
"//conditions:default": [],
"//conditions:default": [":DyldWarningWorkaround"],
}),
)

Expand Down Expand Up @@ -64,6 +64,16 @@ apple_universal_binary(
visibility = ["//visibility:public"],
)

cc_library(
name = "DyldWarningWorkaround",
srcs = [
"Source/DyldWarningWorkaround/DyldWarningWorkaround.c",
"Source/DyldWarningWorkaround/include/objc_dupclass.h",
],
includes = ["Source/DyldWarningWorkaround/include"],
alwayslink = True,
)

# Linting

filegroup(
Expand All @@ -80,9 +90,9 @@ filegroup(
filegroup(
name = "release_files",
srcs = [
"MODULE.bazel",
"BUILD",
"LICENSE",
"MODULE.bazel",
"//:LintInputs",
"//Tests:BUILD",
"//bazel:release_files",
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
[SimplyDanny](https://github.com/SimplyDanny)
[#4894](https://github.com/realm/SwiftLint/issues/4894)

* Workaround dyld warning about SwiftSyntax classes.
[keith](https://github.com/keith)
[#4782](https://github.com/realm/SwiftLint/issues/4782)

## 0.51.0: bzllint

#### Breaking
Expand Down
2 changes: 2 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ let package = Package(
.product(name: "SwiftParser", package: "swift-syntax"),
.product(name: "SwiftOperators", package: "swift-syntax"),
"SwiftyTextTable",
.target(name: "DyldWarningWorkaround", condition: .when(platforms: [.macOS])),
"Yams",
.product(name: "CryptoSwift", package: "CryptoSwift", condition: .when(platforms: [.linux]))
]
),
.target(name: "DyldWarningWorkaround"),
.target(
name: "SwiftLintTestHelpers",
dependencies: [
Expand Down
15 changes: 15 additions & 0 deletions Source/DyldWarningWorkaround/DyldWarningWorkaround.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifdef __APPLE__

#include "objc_dupclass.h"

OBJC_DUPCLASS(_TtC11SwiftSyntax11SyntaxArena);
OBJC_DUPCLASS(_TtC11SwiftSyntax13SyntaxVisitor);
OBJC_DUPCLASS(_TtC11SwiftSyntax14SyntaxRewriter);
OBJC_DUPCLASS(_TtC11SwiftSyntax16BumpPtrAllocator);
OBJC_DUPCLASS(_TtC11SwiftSyntax16SyntaxAnyVisitor);
OBJC_DUPCLASS(_TtC11SwiftSyntax18ParsingSyntaxArena);
OBJC_DUPCLASS(_TtC11SwiftSyntax23SourceLocationConverter);
OBJC_DUPCLASS(_TtC11SwiftSyntax26IncrementalParseTransition);
OBJC_DUPCLASS(_TtC11SwiftSyntax35IncrementalParseReusedNodeCollector);

#endif // __APPLE__
19 changes: 19 additions & 0 deletions Source/DyldWarningWorkaround/include/objc_dupclass.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// https://github.com/keith/objc_dupclass
#include <stdint.h>

// TODO: This isn't entirely accurate, but I'm not sure how to more accurately determine
#if (defined(__arm64__) || defined(DUPCLASS_FORCE_DATA_CONST)) && !defined(DUPCLASS_FORCE_DATA)
#define SECTION "__DATA_CONST"
#else
#define SECTION "__DATA"
#endif

// Struct layout from https://github.com/apple-oss-distributions/objc4/blob/8701d5672d3fd3cd817aeb84db1077aafe1a1604/runtime/objc-abi.h#L175-L183
#define OBJC_DUPCLASS(kclass) \
__attribute__((used)) __attribute__((visibility("hidden"))) \
static struct { uint32_t version; uint32_t flags; const char name[64]; } \
const __duplicate_class_##kclass = { 0, 0, #kclass }; \
\
__attribute__((used)) __attribute__((visibility("hidden"))) \
__attribute__((section (SECTION",__objc_dupclass"))) \
const void* __set___objc_dupclass_sym___duplicate_class_##kclass = &__duplicate_class_##kclass

0 comments on commit 1892c84

Please sign in to comment.