[Serialization] Restrict resilient swiftmodules to the compiler that built them

Introduce a new loading restriction that is more strict than the serialization
version check on swiftmodules. Tagged compilers will only load
library-evolution enabled swiftmodules that are produced by a compiler with the
exact same revision id. This will be more reliable in production
environments than using the serialization version which we forgot to
update from time to time. This shouldn't affect development compilers that
will still load any module with a compatible serialization version.

rdar://83105234
This commit is contained in:
Alexis Laferrière
2021-06-01 16:57:40 -07:00
parent 2cd0d5e1d3
commit 5c2122a08c
7 changed files with 121 additions and 3 deletions

View File

@@ -303,6 +303,35 @@ validateControlBlock(llvm::BitstreamCursor &cursor,
result.sdkName = blobData;
break;
}
case control_block::REVISION: {
// Tagged compilers should load only resilient modules if they were
// produced by the exact same version.
// Disable this restriction for compiler testing by setting this
// env var to any value.
static const char* ignoreRevision =
::getenv("SWIFT_DEBUG_IGNORE_SWIFTMODULE_REVISION");
if (ignoreRevision)
break;
// Override this env var for testing, forcing the behavior of a tagged
// compiler and using the env var value to override this compiler's
// revision.
static const char* forcedDebugRevision =
::getenv("SWIFT_DEBUG_FORCE_SWIFTMODULE_REVISION");
bool isCompilerTagged = forcedDebugRevision ||
- !version::Version::getCurrentCompilerVersion().empty();
StringRef moduleRevision = blobData;
if (isCompilerTagged && !moduleRevision.empty()) {
std::string compilerRevision = forcedDebugRevision ?
forcedDebugRevision : version::getSwiftRevision();
if (moduleRevision != compilerRevision)
result.status = Status::RevisionIncompatible;
}
break;
}
default:
// Unknown metadata record, possibly for use by a future version of the
// module format.