mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
serialization: obfuscate the serialized search paths
We noticed some Swift clients rely on the serialized search paths in the module to find dependencies and droping these paths altogether can lead to build failures like rdar://85840921. This change teaches the serialization to obfuscate the search paths and the deserialization to recover them. This allows clients to keep accessing these paths without exposing them when shipping the module to other users.
This commit is contained in:
@@ -405,6 +405,8 @@ public:
|
|||||||
virtual void collectBasicSourceFileInfo(
|
virtual void collectBasicSourceFileInfo(
|
||||||
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const {}
|
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const {}
|
||||||
|
|
||||||
|
virtual void collectSerializedSearchPath(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) const {}
|
||||||
static bool classof(const FileUnit *file) {
|
static bool classof(const FileUnit *file) {
|
||||||
return file->getKind() == FileUnitKind::SerializedAST ||
|
return file->getKind() == FileUnitKind::SerializedAST ||
|
||||||
file->getKind() == FileUnitKind::ClangModule ||
|
file->getKind() == FileUnitKind::ClangModule ||
|
||||||
|
|||||||
@@ -833,6 +833,8 @@ public:
|
|||||||
void collectBasicSourceFileInfo(
|
void collectBasicSourceFileInfo(
|
||||||
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const;
|
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const;
|
||||||
|
|
||||||
|
void collectSerializedSearchPath(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) const;
|
||||||
/// Retrieve a fingerprint value that summarizes the contents of this module.
|
/// Retrieve a fingerprint value that summarizes the contents of this module.
|
||||||
///
|
///
|
||||||
/// This interface hash a of a module is guaranteed to change if the interface
|
/// This interface hash a of a module is guaranteed to change if the interface
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ public:
|
|||||||
/// specified in LLDB from the target.source-map entries.
|
/// specified in LLDB from the target.source-map entries.
|
||||||
PathRemapper SearchPathRemapper;
|
PathRemapper SearchPathRemapper;
|
||||||
|
|
||||||
|
/// Recover the search paths deserialized from .swiftmodule files to their
|
||||||
|
/// original form.
|
||||||
|
PathObfuscator DeserializedPathRecoverer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static StringRef
|
static StringRef
|
||||||
pathStringFromFrameworkSearchPath(const FrameworkSearchPath &next) {
|
pathStringFromFrameworkSearchPath(const FrameworkSearchPath &next) {
|
||||||
|
|||||||
@@ -58,6 +58,21 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PathObfuscator {
|
||||||
|
PathRemapper obfuscator, recoverer;
|
||||||
|
public:
|
||||||
|
void addMapping(StringRef FromPrefix, StringRef ToPrefix) {
|
||||||
|
obfuscator.addMapping(FromPrefix, ToPrefix);
|
||||||
|
recoverer.addMapping(ToPrefix, FromPrefix);
|
||||||
|
}
|
||||||
|
std::string obfuscate(StringRef Path) const {
|
||||||
|
return obfuscator.remapPath(Path);
|
||||||
|
}
|
||||||
|
std::string recover(StringRef Path) const {
|
||||||
|
return recoverer.remapPath(Path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
#endif // SWIFT_BASIC_PATHREMAPPER_H
|
#endif // SWIFT_BASIC_PATHREMAPPER_H
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "swift/Basic/FileTypes.h"
|
#include "swift/Basic/FileTypes.h"
|
||||||
#include "swift/Basic/Version.h"
|
#include "swift/Basic/Version.h"
|
||||||
|
#include "swift/Basic/PathRemapper.h"
|
||||||
#include "swift/Frontend/FrontendInputsAndOutputs.h"
|
#include "swift/Frontend/FrontendInputsAndOutputs.h"
|
||||||
#include "swift/Frontend/InputFile.h"
|
#include "swift/Frontend/InputFile.h"
|
||||||
#include "llvm/ADT/Hashing.h"
|
#include "llvm/ADT/Hashing.h"
|
||||||
@@ -437,6 +438,10 @@ public:
|
|||||||
/// Whether to include symbols with SPI information in the symbol graph.
|
/// Whether to include symbols with SPI information in the symbol graph.
|
||||||
bool IncludeSPISymbolsInSymbolGraph = false;
|
bool IncludeSPISymbolsInSymbolGraph = false;
|
||||||
|
|
||||||
|
/// This is used to obfuscate the serialized search paths so we don't have
|
||||||
|
/// to encode the actual paths into the .swiftmodule file.
|
||||||
|
PathObfuscator serializedPathObfuscator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool canActionEmitDependencies(ActionType);
|
static bool canActionEmitDependencies(ActionType);
|
||||||
static bool canActionEmitReferenceDependencies(ActionType);
|
static bool canActionEmitReferenceDependencies(ActionType);
|
||||||
|
|||||||
@@ -165,6 +165,10 @@ def print_clang_stats : Flag<["-"], "print-clang-stats">,
|
|||||||
|
|
||||||
def serialize_debugging_options : Flag<["-"], "serialize-debugging-options">,
|
def serialize_debugging_options : Flag<["-"], "serialize-debugging-options">,
|
||||||
HelpText<"Always serialize options for debugging (default: only for apps)">;
|
HelpText<"Always serialize options for debugging (default: only for apps)">;
|
||||||
|
|
||||||
|
def serialized_path_obfuscate : Separate<["-"], "serialized-path-obfuscate">,
|
||||||
|
HelpText<"Remap source paths in debug info">, MetaVarName<"<prefix=replacement>">;
|
||||||
|
|
||||||
def no_serialize_debugging_options :
|
def no_serialize_debugging_options :
|
||||||
Flag<["-"], "no-serialize-debugging-options">,
|
Flag<["-"], "no-serialize-debugging-options">,
|
||||||
HelpText<"Never serialize options for debugging (default: only for apps)">;
|
HelpText<"Never serialize options for debugging (default: only for apps)">;
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ namespace swift {
|
|||||||
/// Path prefixes that should be rewritten in debug info.
|
/// Path prefixes that should be rewritten in debug info.
|
||||||
PathRemapper DebuggingOptionsPrefixMap;
|
PathRemapper DebuggingOptionsPrefixMap;
|
||||||
|
|
||||||
|
/// Obfuscate the serialized paths so we don't have the actual paths encoded
|
||||||
|
/// in the .swiftmodule file.
|
||||||
|
PathObfuscator PathObfuscator;
|
||||||
|
|
||||||
/// Describes a single-file dependency for this module, along with the
|
/// Describes a single-file dependency for this module, along with the
|
||||||
/// appropriate strategy for how to verify if it's up-to-date.
|
/// appropriate strategy for how to verify if it's up-to-date.
|
||||||
class FileDependency {
|
class FileDependency {
|
||||||
|
|||||||
@@ -465,6 +465,9 @@ public:
|
|||||||
virtual void collectBasicSourceFileInfo(
|
virtual void collectBasicSourceFileInfo(
|
||||||
llvm::function_ref<void(const BasicSourceFileInfo &)>) const override;
|
llvm::function_ref<void(const BasicSourceFileInfo &)>) const override;
|
||||||
|
|
||||||
|
virtual void collectSerializedSearchPath(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) const override;
|
||||||
|
|
||||||
static bool classof(const FileUnit *file) {
|
static bool classof(const FileUnit *file) {
|
||||||
return file->getKind() == FileUnitKind::SerializedAST;
|
return file->getKind() == FileUnitKind::SerializedAST;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ struct ValidationInfo {
|
|||||||
/// \sa validateSerializedAST()
|
/// \sa validateSerializedAST()
|
||||||
class ExtendedValidationInfo {
|
class ExtendedValidationInfo {
|
||||||
SmallVector<StringRef, 4> ExtraClangImporterOpts;
|
SmallVector<StringRef, 4> ExtraClangImporterOpts;
|
||||||
StringRef SDKPath;
|
std::string SDKPath;
|
||||||
StringRef ModuleABIName;
|
StringRef ModuleABIName;
|
||||||
struct {
|
struct {
|
||||||
unsigned ArePrivateImportsEnabled : 1;
|
unsigned ArePrivateImportsEnabled : 1;
|
||||||
@@ -121,7 +121,7 @@ public:
|
|||||||
ExtendedValidationInfo() : Bits() {}
|
ExtendedValidationInfo() : Bits() {}
|
||||||
|
|
||||||
StringRef getSDKPath() const { return SDKPath; }
|
StringRef getSDKPath() const { return SDKPath; }
|
||||||
void setSDKPath(StringRef path) {
|
void setSDKPath(std::string path) {
|
||||||
assert(SDKPath.empty());
|
assert(SDKPath.empty());
|
||||||
SDKPath = path;
|
SDKPath = path;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1808,6 +1808,15 @@ void ModuleDecl::collectBasicSourceFileInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModuleDecl::collectSerializedSearchPath(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) const {
|
||||||
|
for (const FileUnit *fileUnit : getFiles()) {
|
||||||
|
if (auto *serialized = dyn_cast<LoadedFile>(fileUnit)) {
|
||||||
|
serialized->collectSerializedSearchPath(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Fingerprint ModuleDecl::getFingerprint() const {
|
Fingerprint ModuleDecl::getFingerprint() const {
|
||||||
StableHasher hasher = StableHasher::defaultHasher();
|
StableHasher hasher = StableHasher::defaultHasher();
|
||||||
SmallVector<Fingerprint, 16> FPs;
|
SmallVector<Fingerprint, 16> FPs;
|
||||||
|
|||||||
@@ -292,6 +292,10 @@ bool ArgsToFrontendOptionsConverter::convert(
|
|||||||
|
|
||||||
Opts.HermeticSealAtLink = Args.hasArg(OPT_experimental_hermetic_seal_at_link);
|
Opts.HermeticSealAtLink = Args.hasArg(OPT_experimental_hermetic_seal_at_link);
|
||||||
|
|
||||||
|
for (auto A : Args.getAllArgValues(options::OPT_serialized_path_obfuscate)) {
|
||||||
|
auto SplitMap = StringRef(A).split('=');
|
||||||
|
Opts.serializedPathObfuscator.addMapping(SplitMap.first, SplitMap.second);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1214,6 +1214,11 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts,
|
|||||||
Opts.PlaceholderDependencyModuleMap = A->getValue();
|
Opts.PlaceholderDependencyModuleMap = A->getValue();
|
||||||
if (const Arg *A = Args.getLastArg(OPT_batch_scan_input_file))
|
if (const Arg *A = Args.getLastArg(OPT_batch_scan_input_file))
|
||||||
Opts.BatchScanInputFilePath = A->getValue();
|
Opts.BatchScanInputFilePath = A->getValue();
|
||||||
|
|
||||||
|
for (auto A : Args.getAllArgValues(options::OPT_serialized_path_obfuscate)) {
|
||||||
|
auto SplitMap = StringRef(A).split('=');
|
||||||
|
Opts.DeserializedPathRecoverer.addMapping(SplitMap.first, SplitMap.second);
|
||||||
|
}
|
||||||
// Opts.RuntimeIncludePath is set by calls to
|
// Opts.RuntimeIncludePath is set by calls to
|
||||||
// setRuntimeIncludePath() or setMainExecutablePath().
|
// setRuntimeIncludePath() or setMainExecutablePath().
|
||||||
// Opts.RuntimeImportPath is set by calls to
|
// Opts.RuntimeImportPath is set by calls to
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
|
|||||||
opts.SerializeOptionsForDebugging.getValueOr(
|
opts.SerializeOptionsForDebugging.getValueOr(
|
||||||
!module->isExternallyConsumed());
|
!module->isExternallyConsumed());
|
||||||
|
|
||||||
|
serializationOpts.PathObfuscator = opts.serializedPathObfuscator;
|
||||||
if (serializationOpts.SerializeOptionsForDebugging &&
|
if (serializationOpts.SerializeOptionsForDebugging &&
|
||||||
opts.DebugPrefixSerializedDebuggingOptions) {
|
opts.DebugPrefixSerializedDebuggingOptions) {
|
||||||
serializationOpts.DebuggingOptionsPrefixMap =
|
serializationOpts.DebuggingOptionsPrefixMap =
|
||||||
|
|||||||
@@ -361,6 +361,7 @@ ModuleFile::getModuleName(ASTContext &Ctx, StringRef modulePath,
|
|||||||
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
|
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
|
||||||
modulePath.str(), std::move(newBuf), nullptr, nullptr,
|
modulePath.str(), std::move(newBuf), nullptr, nullptr,
|
||||||
/*isFramework*/ isFramework, Ctx.SILOpts.EnableOSSAModules,
|
/*isFramework*/ isFramework, Ctx.SILOpts.EnableOSSAModules,
|
||||||
|
Ctx.SearchPathOpts.DeserializedPathRecoverer,
|
||||||
loadedModuleFile);
|
loadedModuleFile);
|
||||||
Name = loadedModuleFile->Name.str();
|
Name = loadedModuleFile->Name.str();
|
||||||
return std::move(moduleBuf.get());
|
return std::move(moduleBuf.get());
|
||||||
@@ -999,6 +1000,13 @@ Optional<CommentInfo> ModuleFile::getCommentForDecl(const Decl *D) const {
|
|||||||
return getCommentForDeclByUSR(USRBuffer.str());
|
return getCommentForDeclByUSR(USRBuffer.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModuleFile::collectSerializedSearchPath(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) const {
|
||||||
|
for (auto path: Core->SearchPaths) {
|
||||||
|
callback(path.Path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ModuleFile::collectBasicSourceFileInfo(
|
void ModuleFile::collectBasicSourceFileInfo(
|
||||||
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const {
|
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const {
|
||||||
if (Core->SourceFileListData.empty())
|
if (Core->SourceFileListData.empty())
|
||||||
|
|||||||
@@ -743,7 +743,8 @@ public:
|
|||||||
Optional<Fingerprint> loadFingerprint(const IterableDeclContext *IDC) const;
|
Optional<Fingerprint> loadFingerprint(const IterableDeclContext *IDC) const;
|
||||||
void collectBasicSourceFileInfo(
|
void collectBasicSourceFileInfo(
|
||||||
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const;
|
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const;
|
||||||
|
void collectSerializedSearchPath(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) const;
|
||||||
|
|
||||||
// MARK: Deserialization interface
|
// MARK: Deserialization interface
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,8 @@ static bool enterTopLevelModuleBlock(llvm::BitstreamCursor &cursor,
|
|||||||
/// Returns true on success.
|
/// Returns true on success.
|
||||||
static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
|
static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
|
||||||
SmallVectorImpl<uint64_t> &scratch,
|
SmallVectorImpl<uint64_t> &scratch,
|
||||||
ExtendedValidationInfo &extendedInfo) {
|
ExtendedValidationInfo &extendedInfo,
|
||||||
|
PathObfuscator &pathRecoverer) {
|
||||||
while (!cursor.AtEndOfStream()) {
|
while (!cursor.AtEndOfStream()) {
|
||||||
Expected<llvm::BitstreamEntry> maybeEntry = cursor.advance();
|
Expected<llvm::BitstreamEntry> maybeEntry = cursor.advance();
|
||||||
if (!maybeEntry) {
|
if (!maybeEntry) {
|
||||||
@@ -119,7 +120,7 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
|
|||||||
unsigned kind = maybeKind.get();
|
unsigned kind = maybeKind.get();
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case options_block::SDK_PATH:
|
case options_block::SDK_PATH:
|
||||||
extendedInfo.setSDKPath(blobData);
|
extendedInfo.setSDKPath(pathRecoverer.recover(blobData));
|
||||||
break;
|
break;
|
||||||
case options_block::XCC:
|
case options_block::XCC:
|
||||||
extendedInfo.addExtraClangImporterOption(blobData);
|
extendedInfo.addExtraClangImporterOption(blobData);
|
||||||
@@ -171,7 +172,8 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
|
|||||||
static ValidationInfo validateControlBlock(
|
static ValidationInfo validateControlBlock(
|
||||||
llvm::BitstreamCursor &cursor, SmallVectorImpl<uint64_t> &scratch,
|
llvm::BitstreamCursor &cursor, SmallVectorImpl<uint64_t> &scratch,
|
||||||
std::pair<uint16_t, uint16_t> expectedVersion, bool requiresOSSAModules,
|
std::pair<uint16_t, uint16_t> expectedVersion, bool requiresOSSAModules,
|
||||||
ExtendedValidationInfo *extendedInfo) {
|
ExtendedValidationInfo *extendedInfo,
|
||||||
|
PathObfuscator &pathRecoverer) {
|
||||||
// The control block is malformed until we've at least read a major version
|
// The control block is malformed until we've at least read a major version
|
||||||
// number.
|
// number.
|
||||||
ValidationInfo result;
|
ValidationInfo result;
|
||||||
@@ -202,7 +204,7 @@ static ValidationInfo validateControlBlock(
|
|||||||
result.status = Status::Malformed;
|
result.status = Status::Malformed;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (!readOptionsBlock(cursor, scratch, *extendedInfo)) {
|
if (!readOptionsBlock(cursor, scratch, *extendedInfo, pathRecoverer)) {
|
||||||
result.status = Status::Malformed;
|
result.status = Status::Malformed;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -465,10 +467,11 @@ ValidationInfo serialization::validateSerializedAST(
|
|||||||
result.status = Status::Malformed;
|
result.status = Status::Malformed;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
PathObfuscator localObfuscator;
|
||||||
result = validateControlBlock(
|
result = validateControlBlock(
|
||||||
cursor, scratch,
|
cursor, scratch,
|
||||||
{SWIFTMODULE_VERSION_MAJOR, SWIFTMODULE_VERSION_MINOR},
|
{SWIFTMODULE_VERSION_MAJOR, SWIFTMODULE_VERSION_MINOR},
|
||||||
requiresOSSAModules, extendedInfo);
|
requiresOSSAModules, extendedInfo, localObfuscator);
|
||||||
if (result.status == Status::Malformed)
|
if (result.status == Status::Malformed)
|
||||||
return result;
|
return result;
|
||||||
} else if (dependencies &&
|
} else if (dependencies &&
|
||||||
@@ -938,7 +941,7 @@ getActualImportControl(unsigned rawValue) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleFileSharedCore::readModuleDocIfPresent() {
|
bool ModuleFileSharedCore::readModuleDocIfPresent(PathObfuscator &pathRecoverer) {
|
||||||
if (!this->ModuleDocInputBuffer)
|
if (!this->ModuleDocInputBuffer)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -977,7 +980,7 @@ bool ModuleFileSharedCore::readModuleDocIfPresent() {
|
|||||||
info = validateControlBlock(
|
info = validateControlBlock(
|
||||||
docCursor, scratch, {SWIFTDOC_VERSION_MAJOR, SWIFTDOC_VERSION_MINOR},
|
docCursor, scratch, {SWIFTDOC_VERSION_MAJOR, SWIFTDOC_VERSION_MINOR},
|
||||||
RequiresOSSAModules,
|
RequiresOSSAModules,
|
||||||
/*extendedInfo*/ nullptr);
|
/*extendedInfo*/ nullptr, pathRecoverer);
|
||||||
if (info.status != Status::Valid)
|
if (info.status != Status::Valid)
|
||||||
return false;
|
return false;
|
||||||
// Check that the swiftdoc is actually for this module.
|
// Check that the swiftdoc is actually for this module.
|
||||||
@@ -1083,7 +1086,7 @@ bool ModuleFileSharedCore::readDeclLocsBlock(llvm::BitstreamCursor &cursor) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleFileSharedCore::readModuleSourceInfoIfPresent() {
|
bool ModuleFileSharedCore::readModuleSourceInfoIfPresent(PathObfuscator &pathRecoverer) {
|
||||||
if (!this->ModuleSourceInfoInputBuffer)
|
if (!this->ModuleSourceInfoInputBuffer)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -1121,7 +1124,8 @@ bool ModuleFileSharedCore::readModuleSourceInfoIfPresent() {
|
|||||||
infoCursor, scratch,
|
infoCursor, scratch,
|
||||||
{SWIFTSOURCEINFO_VERSION_MAJOR, SWIFTSOURCEINFO_VERSION_MINOR},
|
{SWIFTSOURCEINFO_VERSION_MAJOR, SWIFTSOURCEINFO_VERSION_MINOR},
|
||||||
RequiresOSSAModules,
|
RequiresOSSAModules,
|
||||||
/*extendedInfo*/ nullptr);
|
/*extendedInfo*/ nullptr,
|
||||||
|
pathRecoverer);
|
||||||
if (info.status != Status::Valid)
|
if (info.status != Status::Valid)
|
||||||
return false;
|
return false;
|
||||||
// Check that the swiftsourceinfo is actually for this module.
|
// Check that the swiftsourceinfo is actually for this module.
|
||||||
@@ -1196,7 +1200,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
|
|||||||
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
|
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
|
||||||
std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
|
std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
|
||||||
bool isFramework, bool requiresOSSAModules,
|
bool isFramework, bool requiresOSSAModules,
|
||||||
serialization::ValidationInfo &info)
|
serialization::ValidationInfo &info, PathObfuscator &pathRecoverer)
|
||||||
: ModuleInputBuffer(std::move(moduleInputBuffer)),
|
: ModuleInputBuffer(std::move(moduleInputBuffer)),
|
||||||
ModuleDocInputBuffer(std::move(moduleDocInputBuffer)),
|
ModuleDocInputBuffer(std::move(moduleDocInputBuffer)),
|
||||||
ModuleSourceInfoInputBuffer(std::move(moduleSourceInfoInputBuffer)),
|
ModuleSourceInfoInputBuffer(std::move(moduleSourceInfoInputBuffer)),
|
||||||
@@ -1247,7 +1251,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
|
|||||||
info = validateControlBlock(
|
info = validateControlBlock(
|
||||||
cursor, scratch,
|
cursor, scratch,
|
||||||
{SWIFTMODULE_VERSION_MAJOR, SWIFTMODULE_VERSION_MINOR},
|
{SWIFTMODULE_VERSION_MAJOR, SWIFTMODULE_VERSION_MINOR},
|
||||||
RequiresOSSAModules, &extInfo);
|
RequiresOSSAModules, &extInfo, pathRecoverer);
|
||||||
if (info.status != Status::Valid) {
|
if (info.status != Status::Valid) {
|
||||||
error(info.status);
|
error(info.status);
|
||||||
return;
|
return;
|
||||||
@@ -1372,7 +1376,8 @@ ModuleFileSharedCore::ModuleFileSharedCore(
|
|||||||
bool isSystem;
|
bool isSystem;
|
||||||
input_block::SearchPathLayout::readRecord(scratch, isFramework,
|
input_block::SearchPathLayout::readRecord(scratch, isFramework,
|
||||||
isSystem);
|
isSystem);
|
||||||
SearchPaths.push_back({blobData, isFramework, isSystem});
|
SearchPaths.push_back({pathRecoverer.recover(blobData), isFramework,
|
||||||
|
isSystem});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case input_block::MODULE_INTERFACE_PATH: {
|
case input_block::MODULE_INTERFACE_PATH: {
|
||||||
@@ -1572,8 +1577,8 @@ ModuleFileSharedCore::ModuleFileSharedCore(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Read source info file.
|
// Read source info file.
|
||||||
readModuleSourceInfoIfPresent();
|
readModuleSourceInfoIfPresent(pathRecoverer);
|
||||||
if (!readModuleDocIfPresent()) {
|
if (!readModuleDocIfPresent(pathRecoverer)) {
|
||||||
info.status = error(Status::MalformedDocumentation);
|
info.status = error(Status::MalformedDocumentation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ private:
|
|||||||
SmallVector<Dependency, 8> Dependencies;
|
SmallVector<Dependency, 8> Dependencies;
|
||||||
|
|
||||||
struct SearchPath {
|
struct SearchPath {
|
||||||
StringRef Path;
|
std::string Path;
|
||||||
bool IsFramework;
|
bool IsFramework;
|
||||||
bool IsSystem;
|
bool IsSystem;
|
||||||
};
|
};
|
||||||
@@ -374,7 +374,7 @@ private:
|
|||||||
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
|
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
|
||||||
std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
|
std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
|
||||||
bool isFramework, bool requiresOSSAModules,
|
bool isFramework, bool requiresOSSAModules,
|
||||||
serialization::ValidationInfo &info);
|
serialization::ValidationInfo &info, PathObfuscator &pathRecoverer);
|
||||||
|
|
||||||
/// Change the status of the current module.
|
/// Change the status of the current module.
|
||||||
Status error(Status issue) {
|
Status error(Status issue) {
|
||||||
@@ -464,7 +464,7 @@ private:
|
|||||||
/// Loads data from #ModuleDocInputBuffer.
|
/// Loads data from #ModuleDocInputBuffer.
|
||||||
///
|
///
|
||||||
/// Returns false if there was an error.
|
/// Returns false if there was an error.
|
||||||
bool readModuleDocIfPresent();
|
bool readModuleDocIfPresent(PathObfuscator &pathRecoverer);
|
||||||
|
|
||||||
/// Reads the source loc block, which contains USR to decl location mapping.
|
/// Reads the source loc block, which contains USR to decl location mapping.
|
||||||
///
|
///
|
||||||
@@ -474,7 +474,7 @@ private:
|
|||||||
/// Loads data from #ModuleSourceInfoInputBuffer.
|
/// Loads data from #ModuleSourceInfoInputBuffer.
|
||||||
///
|
///
|
||||||
/// Returns false if there was an error.
|
/// Returns false if there was an error.
|
||||||
bool readModuleSourceInfoIfPresent();
|
bool readModuleSourceInfoIfPresent(PathObfuscator &pathRecoverer);
|
||||||
|
|
||||||
/// Read an on-disk decl hash table stored in
|
/// Read an on-disk decl hash table stored in
|
||||||
/// \c sourceinfo_block::DeclUSRSLayout format.
|
/// \c sourceinfo_block::DeclUSRSLayout format.
|
||||||
@@ -510,12 +510,13 @@ public:
|
|||||||
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
|
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
|
||||||
std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
|
std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
|
||||||
bool isFramework, bool requiresOSSAModules,
|
bool isFramework, bool requiresOSSAModules,
|
||||||
|
PathObfuscator &pathRecoverer,
|
||||||
std::shared_ptr<const ModuleFileSharedCore> &theModule) {
|
std::shared_ptr<const ModuleFileSharedCore> &theModule) {
|
||||||
serialization::ValidationInfo info;
|
serialization::ValidationInfo info;
|
||||||
auto *core = new ModuleFileSharedCore(
|
auto *core = new ModuleFileSharedCore(
|
||||||
std::move(moduleInputBuffer), std::move(moduleDocInputBuffer),
|
std::move(moduleInputBuffer), std::move(moduleDocInputBuffer),
|
||||||
std::move(moduleSourceInfoInputBuffer), isFramework,
|
std::move(moduleSourceInfoInputBuffer), isFramework,
|
||||||
requiresOSSAModules, info);
|
requiresOSSAModules, info, pathRecoverer);
|
||||||
if (!moduleInterfacePath.empty()) {
|
if (!moduleInterfacePath.empty()) {
|
||||||
ArrayRef<char> path;
|
ArrayRef<char> path;
|
||||||
core->allocateBuffer(path, moduleInterfacePath);
|
core->allocateBuffer(path, moduleInterfacePath);
|
||||||
|
|||||||
@@ -1077,9 +1077,11 @@ void Serializer::writeHeader(const SerializationOptions &options) {
|
|||||||
options_block::XCCLayout XCC(Out);
|
options_block::XCCLayout XCC(Out);
|
||||||
|
|
||||||
const auto &PathRemapper = options.DebuggingOptionsPrefixMap;
|
const auto &PathRemapper = options.DebuggingOptionsPrefixMap;
|
||||||
|
const auto &PathObfuscator = options.PathObfuscator;
|
||||||
|
auto sdkPath = M->getASTContext().SearchPathOpts.SDKPath;
|
||||||
SDKPath.emit(
|
SDKPath.emit(
|
||||||
ScratchRecord,
|
ScratchRecord,
|
||||||
PathRemapper.remapPath(M->getASTContext().SearchPathOpts.SDKPath));
|
PathObfuscator.obfuscate(PathRemapper.remapPath(sdkPath)));
|
||||||
auto &Opts = options.ExtraClangOptions;
|
auto &Opts = options.ExtraClangOptions;
|
||||||
for (auto Arg = Opts.begin(), E = Opts.end(); Arg != E; ++Arg) {
|
for (auto Arg = Opts.begin(), E = Opts.end(); Arg != E; ++Arg) {
|
||||||
StringRef arg(*Arg);
|
StringRef arg(*Arg);
|
||||||
@@ -1157,16 +1159,17 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
|
|||||||
input_block::ModuleInterfaceLayout ModuleInterface(Out);
|
input_block::ModuleInterfaceLayout ModuleInterface(Out);
|
||||||
|
|
||||||
if (options.SerializeOptionsForDebugging) {
|
if (options.SerializeOptionsForDebugging) {
|
||||||
|
const auto &PathObfuscator = options.PathObfuscator;
|
||||||
const auto &PathMapper = options.DebuggingOptionsPrefixMap;
|
const auto &PathMapper = options.DebuggingOptionsPrefixMap;
|
||||||
const SearchPathOptions &searchPathOpts = M->getASTContext().SearchPathOpts;
|
const SearchPathOptions &searchPathOpts = M->getASTContext().SearchPathOpts;
|
||||||
// Put the framework search paths first so that they'll be preferred upon
|
// Put the framework search paths first so that they'll be preferred upon
|
||||||
// deserialization.
|
// deserialization.
|
||||||
for (auto &framepath : searchPathOpts.FrameworkSearchPaths)
|
for (auto &framepath : searchPathOpts.FrameworkSearchPaths)
|
||||||
SearchPath.emit(ScratchRecord, /*framework=*/true, framepath.IsSystem,
|
SearchPath.emit(ScratchRecord, /*framework=*/true, framepath.IsSystem,
|
||||||
PathMapper.remapPath(framepath.Path));
|
PathObfuscator.obfuscate(PathMapper.remapPath(framepath.Path)));
|
||||||
for (auto &path : searchPathOpts.ImportSearchPaths)
|
for (auto &path : searchPathOpts.ImportSearchPaths)
|
||||||
SearchPath.emit(ScratchRecord, /*framework=*/false, /*system=*/false,
|
SearchPath.emit(ScratchRecord, /*framework=*/false, /*system=*/false,
|
||||||
PathMapper.remapPath(path));
|
PathObfuscator.obfuscate(PathMapper.remapPath(path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: We're not using StringMap here because we don't need to own the
|
// Note: We're not using StringMap here because we don't need to own the
|
||||||
|
|||||||
@@ -404,7 +404,9 @@ llvm::ErrorOr<ModuleDependencies> SerializedModuleLoaderBase::scanModuleFile(
|
|||||||
bool isFramework = false;
|
bool isFramework = false;
|
||||||
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
|
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
|
||||||
modulePath.str(), std::move(moduleBuf.get()), nullptr, nullptr,
|
modulePath.str(), std::move(moduleBuf.get()), nullptr, nullptr,
|
||||||
isFramework, isRequiredOSSAModules(), loadedModuleFile);
|
isFramework, isRequiredOSSAModules(),
|
||||||
|
Ctx.SearchPathOpts.DeserializedPathRecoverer,
|
||||||
|
loadedModuleFile);
|
||||||
|
|
||||||
const std::string moduleDocPath;
|
const std::string moduleDocPath;
|
||||||
const std::string sourceInfoPath;
|
const std::string sourceInfoPath;
|
||||||
@@ -730,7 +732,9 @@ LoadedFile *SerializedModuleLoaderBase::loadAST(
|
|||||||
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
|
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
|
||||||
moduleInterfacePath, std::move(moduleInputBuffer),
|
moduleInterfacePath, std::move(moduleInputBuffer),
|
||||||
std::move(moduleDocInputBuffer), std::move(moduleSourceInfoInputBuffer),
|
std::move(moduleDocInputBuffer), std::move(moduleSourceInfoInputBuffer),
|
||||||
isFramework, isRequiredOSSAModules(), loadedModuleFileCore);
|
isFramework, isRequiredOSSAModules(),
|
||||||
|
Ctx.SearchPathOpts.DeserializedPathRecoverer,
|
||||||
|
loadedModuleFileCore);
|
||||||
SerializedASTFile *fileUnit = nullptr;
|
SerializedASTFile *fileUnit = nullptr;
|
||||||
|
|
||||||
if (loadInfo.status == serialization::Status::Valid) {
|
if (loadInfo.status == serialization::Status::Valid) {
|
||||||
@@ -1555,3 +1559,8 @@ void SerializedASTFile::collectBasicSourceFileInfo(
|
|||||||
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const {
|
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const {
|
||||||
File.collectBasicSourceFileInfo(callback);
|
File.collectBasicSourceFileInfo(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SerializedASTFile::collectSerializedSearchPath(
|
||||||
|
llvm::function_ref<void(StringRef)> callback) const {
|
||||||
|
File.collectSerializedSearchPath(callback);
|
||||||
|
}
|
||||||
|
|||||||
13
test/Serialization/path_obfuscator.swift
Normal file
13
test/Serialization/path_obfuscator.swift
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// RUN: %empty-directory(%t)
|
||||||
|
// RUN: %empty-directory(%t.module-cache)
|
||||||
|
// RUN: %target-swift-frontend -emit-module -o %t/Foo.swiftmodule %s -parse-as-library -serialized-path-obfuscate /FOO=/CHANGED_FOO -serialized-path-obfuscate /BAR=/CHANGED_BAR -I /FOO/contents -I /BAR/contents -module-name Foo -serialize-debugging-options
|
||||||
|
// RUN: %target-swift-ide-test -print-module-metadata -module-to-print Foo -enable-swiftsourceinfo -I %t -source-filename %s | %FileCheck %s --check-prefix=CHECK-ORIGINAL
|
||||||
|
// RUN: %target-swift-ide-test -print-module-metadata -module-to-print Foo -enable-swiftsourceinfo -I %t -source-filename %s -serialized-path-obfuscate /FOO=/CHANGED_FOO -serialized-path-obfuscate /BAR=/CHANGED_BAR | %FileCheck %s --check-prefix=CHECK-RECOVER
|
||||||
|
|
||||||
|
public class A {}
|
||||||
|
|
||||||
|
// CHECK-ORIGINAL: /CHANGED_FOO/contents
|
||||||
|
// CHECK-ORIGINAL: /CHANGED_BAR/contents
|
||||||
|
|
||||||
|
// CHECK-RECOVER: /FOO/contents
|
||||||
|
// CHECK-RECOVER: /BAR/contents
|
||||||
@@ -803,6 +803,10 @@ static llvm::cl::opt<std::string>
|
|||||||
llvm::cl::desc("Define a macro for @available"),
|
llvm::cl::desc("Define a macro for @available"),
|
||||||
llvm::cl::cat(Category));
|
llvm::cl::cat(Category));
|
||||||
|
|
||||||
|
static llvm::cl::list<std::string>
|
||||||
|
SerializedPathObfuscate("serialized-path-obfuscate", llvm::cl::desc("Path to access notes file"),
|
||||||
|
llvm::cl::cat(Category));
|
||||||
|
|
||||||
} // namespace options
|
} // namespace options
|
||||||
|
|
||||||
static std::unique_ptr<llvm::MemoryBuffer>
|
static std::unique_ptr<llvm::MemoryBuffer>
|
||||||
@@ -2819,6 +2823,9 @@ static void printModuleMetadata(ModuleDecl *MD) {
|
|||||||
OS << "size=" << info.getFileSize();
|
OS << "size=" << info.getFileSize();
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
});
|
});
|
||||||
|
MD->collectSerializedSearchPath([&](StringRef path) {
|
||||||
|
OS << "searchpath=" << path << ";\n";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int doPrintModuleMetaData(const CompilerInvocation &InitInvok,
|
static int doPrintModuleMetaData(const CompilerInvocation &InitInvok,
|
||||||
@@ -4118,6 +4125,13 @@ int main(int argc, char *argv[]) {
|
|||||||
if (!options::DefineAvailability.empty()) {
|
if (!options::DefineAvailability.empty()) {
|
||||||
InitInvok.getLangOptions().AvailabilityMacros.push_back(options::DefineAvailability);
|
InitInvok.getLangOptions().AvailabilityMacros.push_back(options::DefineAvailability);
|
||||||
}
|
}
|
||||||
|
for (auto map: options::SerializedPathObfuscate) {
|
||||||
|
auto SplitMap = StringRef(map).split('=');
|
||||||
|
InitInvok.getFrontendOptions().serializedPathObfuscator
|
||||||
|
.addMapping(SplitMap.first, SplitMap.second);
|
||||||
|
InitInvok.getSearchPathOptions().DeserializedPathRecoverer
|
||||||
|
.addMapping(SplitMap.first, SplitMap.second);
|
||||||
|
}
|
||||||
InitInvok.getLangOptions().CollectParsedToken = true;
|
InitInvok.getLangOptions().CollectParsedToken = true;
|
||||||
InitInvok.getLangOptions().BuildSyntaxTree = true;
|
InitInvok.getLangOptions().BuildSyntaxTree = true;
|
||||||
InitInvok.getLangOptions().EnableCrossImportOverlays =
|
InitInvok.getLangOptions().EnableCrossImportOverlays =
|
||||||
|
|||||||
Reference in New Issue
Block a user