[clang] [InstallAPI] Capture & compare load commands that may differ per arch slice (PR #87674)
Zixu Wang via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 5 10:57:17 PDT 2024
================
@@ -702,5 +724,179 @@ DylibVerifier::Result DylibVerifier::verifyRemainingSymbols() {
return getState();
}
+bool DylibVerifier::verifyBinaryAttrs(const ArrayRef<Target> ProvidedTargets,
+ const BinaryAttrs &ProvidedBA,
+ const LibAttrs &ProvidedReexports,
+ const LibAttrs &ProvidedClients,
+ const LibAttrs &ProvidedRPaths,
+ const FileType &FT) {
+ assert(!Dylib.empty() && "Need dylib to verify.");
+
+ // Pickup any load commands that can differ per slice to compare.
+ TargetList DylibTargets;
+ LibAttrs DylibReexports;
+ LibAttrs DylibClients;
+ LibAttrs DylibRPaths;
+ for (const std::shared_ptr<RecordsSlice> &RS : Dylib) {
+ DylibTargets.push_back(RS->getTarget());
+ const BinaryAttrs &BinInfo = RS->getBinaryAttrs();
+ for (const StringRef LibName : BinInfo.RexportedLibraries)
+ DylibReexports[LibName].set(DylibTargets.back().Arch);
+ for (const StringRef LibName : BinInfo.AllowableClients)
+ DylibClients[LibName].set(DylibTargets.back().Arch);
+ // Compare attributes that are only representable in >= TBD_V5.
+ if (FT >= FileType::TBD_V5)
+ for (const StringRef Name : BinInfo.RPaths)
+ DylibRPaths[Name].set(DylibTargets.back().Arch);
+ }
+
+ // Check targets first.
+ ArchitectureSet ProvidedArchs = mapToArchitectureSet(ProvidedTargets);
+ ArchitectureSet DylibArchs = mapToArchitectureSet(DylibTargets);
+ if (ProvidedArchs != DylibArchs) {
+ Ctx.Diag->Report(diag::err_architecture_mismatch)
+ << ProvidedArchs << DylibArchs;
+ return false;
+ }
+ auto ProvidedPlatforms = mapToPlatformVersionSet(ProvidedTargets);
+ auto DylibPlatforms = mapToPlatformVersionSet(DylibTargets);
+ if (ProvidedPlatforms != DylibPlatforms) {
+ const bool DiffMinOS =
+ mapToPlatformSet(ProvidedTargets) == mapToPlatformSet(DylibTargets);
+ if (DiffMinOS)
+ Ctx.Diag->Report(diag::warn_platform_mismatch)
+ << ProvidedPlatforms << DylibPlatforms;
+ else {
+ Ctx.Diag->Report(diag::err_platform_mismatch)
+ << ProvidedPlatforms << DylibPlatforms;
+ return false;
+ }
+ }
+
+ // Because InstallAPI requires certain attributes to match across architecture
+ // slices, take the first one to compare those with.
+ const BinaryAttrs &DylibBA = (*Dylib.begin())->getBinaryAttrs();
+
+ if (ProvidedBA.InstallName != DylibBA.InstallName) {
+ Ctx.Diag->Report(diag::err_install_name_mismatch)
+ << ProvidedBA.InstallName << DylibBA.InstallName;
+ return false;
+ }
+
+ if (ProvidedBA.CurrentVersion != DylibBA.CurrentVersion) {
+ Ctx.Diag->Report(diag::err_current_version_mismatch)
+ << ProvidedBA.CurrentVersion << DylibBA.CurrentVersion;
+ return false;
+ }
+
+ if (ProvidedBA.CompatVersion != DylibBA.CompatVersion) {
+ Ctx.Diag->Report(diag::err_compatibility_version_mismatch)
+ << ProvidedBA.CompatVersion << DylibBA.CompatVersion;
+ return false;
+ }
+
+ if (ProvidedBA.AppExtensionSafe != DylibBA.AppExtensionSafe) {
+ Ctx.Diag->Report(diag::err_appextension_safe_mismatch)
+ << (ProvidedBA.AppExtensionSafe ? "true" : "false")
+ << (DylibBA.AppExtensionSafe ? "true" : "false");
+ return false;
+ }
+
+ if (!DylibBA.TwoLevelNamespace) {
+ Ctx.Diag->Report(diag::err_no_twolevel_namespace);
+ return false;
+ }
+
+ if (ProvidedBA.OSLibNotForSharedCache != DylibBA.OSLibNotForSharedCache) {
+ Ctx.Diag->Report(diag::err_shared_cache_eligiblity_mismatch)
+ << (ProvidedBA.OSLibNotForSharedCache ? "true" : "false")
+ << (DylibBA.OSLibNotForSharedCache ? "true" : "false");
+ return false;
+ }
+
+ if (ProvidedBA.ParentUmbrella.empty() && !DylibBA.ParentUmbrella.empty()) {
+ Ctx.Diag->Report(diag::err_parent_umbrella_missing)
+ << "installAPI option" << DylibBA.ParentUmbrella;
+ return false;
+ }
+
+ if (!ProvidedBA.ParentUmbrella.empty() && !DylibBA.ParentUmbrella.empty()) {
----------------
zixu-w wrote:
Should this be
```
!ProvidedBA.ParentUmbrella.empty() && DylibBA.ParentUmbrella.empty()
^ no negation here
```
?
https://github.com/llvm/llvm-project/pull/87674
More information about the cfe-commits
mailing list