Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:56

0001 //===- InstallAPI/DylibVerifier.h -------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H
0010 #define LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H
0011 
0012 #include "clang/Basic/Diagnostic.h"
0013 #include "clang/Basic/SourceManager.h"
0014 #include "clang/InstallAPI/MachO.h"
0015 
0016 namespace clang {
0017 namespace installapi {
0018 struct FrontendAttrs;
0019 
0020 /// A list of InstallAPI verification modes.
0021 enum class VerificationMode {
0022   Invalid,
0023   ErrorsOnly,
0024   ErrorsAndWarnings,
0025   Pedantic,
0026 };
0027 
0028 using LibAttrs = llvm::StringMap<ArchitectureSet>;
0029 using ReexportedInterfaces = llvm::SmallVector<llvm::MachO::InterfaceFile, 8>;
0030 
0031 // Pointers to information about a zippered declaration used for
0032 // querying and reporting violations against different
0033 // declarations that all map to the same symbol.
0034 struct ZipperedDeclSource {
0035   const FrontendAttrs *FA;
0036   clang::SourceManager *SrcMgr;
0037   Target T;
0038 };
0039 using ZipperedDeclSources = std::vector<ZipperedDeclSource>;
0040 
0041 /// Service responsible to tracking state of verification across the
0042 /// lifetime of InstallAPI.
0043 /// As declarations are collected during AST traversal, they are
0044 /// compared as symbols against what is available in the binary dylib.
0045 class DylibVerifier : llvm::MachO::RecordVisitor {
0046 private:
0047   struct SymbolContext;
0048   struct DWARFContext;
0049 
0050 public:
0051   enum class Result { NoVerify, Ignore, Valid, Invalid };
0052   struct VerifierContext {
0053     // Current target being verified against the AST.
0054     llvm::MachO::Target Target;
0055 
0056     // Target specific API from binary.
0057     RecordsSlice *DylibSlice = nullptr;
0058 
0059     // Query state of verification after AST has been traversed.
0060     Result FrontendState = Result::Ignore;
0061 
0062     // First error for AST traversal, which is tied to the target triple.
0063     bool DiscoveredFirstError = false;
0064 
0065     // Determines what kind of banner to print a violation for.
0066     bool PrintArch = false;
0067 
0068     // Engine for reporting violations.
0069     DiagnosticsEngine *Diag = nullptr;
0070 
0071     // Handle diagnostics reporting for target level violations.
0072     void emitDiag(llvm::function_ref<void()> Report, RecordLoc *Loc = nullptr);
0073 
0074     VerifierContext() = default;
0075     VerifierContext(DiagnosticsEngine *Diag) : Diag(Diag) {}
0076   };
0077 
0078   DylibVerifier() = default;
0079 
0080   DylibVerifier(llvm::MachO::Records &&Dylib, ReexportedInterfaces &&Reexports,
0081                 AliasMap Aliases, DiagnosticsEngine *Diag,
0082                 VerificationMode Mode, bool Zippered, bool Demangle,
0083                 StringRef DSYMPath)
0084       : Dylib(std::move(Dylib)), Reexports(std::move(Reexports)),
0085         Aliases(std::move(Aliases)), Mode(Mode), Zippered(Zippered),
0086         Demangle(Demangle), DSYMPath(DSYMPath),
0087         Exports(std::make_unique<SymbolSet>()), Ctx(VerifierContext{Diag}) {}
0088 
0089   Result verify(GlobalRecord *R, const FrontendAttrs *FA);
0090   Result verify(ObjCInterfaceRecord *R, const FrontendAttrs *FA);
0091   Result verify(ObjCIVarRecord *R, const FrontendAttrs *FA,
0092                 const StringRef SuperClass);
0093 
0094   // Scan through dylib slices and report any remaining missing exports.
0095   Result verifyRemainingSymbols();
0096 
0097   /// Compare and report the attributes represented as
0098   /// load commands in the dylib to the attributes provided via options.
0099   bool verifyBinaryAttrs(const ArrayRef<Target> ProvidedTargets,
0100                          const BinaryAttrs &ProvidedBA,
0101                          const LibAttrs &ProvidedReexports,
0102                          const LibAttrs &ProvidedClients,
0103                          const LibAttrs &ProvidedRPaths, const FileType &FT);
0104 
0105   /// Initialize target for verification.
0106   void setTarget(const Target &T);
0107 
0108   /// Release ownership over exports.
0109   std::unique_ptr<SymbolSet> takeExports();
0110 
0111   /// Get result of verification.
0112   Result getState() const { return Ctx.FrontendState; }
0113 
0114   /// Set different source managers to the same diagnostics engine.
0115   void setSourceManager(IntrusiveRefCntPtr<SourceManager> SourceMgr);
0116 
0117 private:
0118   /// Determine whether to compare declaration to symbol in binary.
0119   bool canVerify();
0120 
0121   /// Shared implementation for verifying exported symbols.
0122   Result verifyImpl(Record *R, SymbolContext &SymCtx);
0123 
0124   /// Check if declaration is marked as obsolete, they are
0125   // expected to result in a symbol mismatch.
0126   bool shouldIgnoreObsolete(const Record *R, SymbolContext &SymCtx,
0127                             const Record *DR);
0128 
0129   /// Check if declaration is exported from a reexported library. These
0130   /// symbols should be omitted from the text-api file.
0131   bool shouldIgnoreReexport(const Record *R, SymbolContext &SymCtx) const;
0132 
0133   // Ignore and omit unavailable symbols in zippered libraries.
0134   bool shouldIgnoreZipperedAvailability(const Record *R, SymbolContext &SymCtx);
0135 
0136   // Check if an internal declaration in zippered library has an
0137   // external declaration for a different platform. This results
0138   // in the symbol being in a "separate" platform slice.
0139   bool shouldIgnoreInternalZipperedSymbol(const Record *R,
0140                                           const SymbolContext &SymCtx) const;
0141 
0142   /// Compare the visibility declarations to the linkage of symbol found in
0143   /// dylib.
0144   Result compareVisibility(const Record *R, SymbolContext &SymCtx,
0145                            const Record *DR);
0146 
0147   /// An ObjCInterfaceRecord can represent up to three symbols. When verifying,
0148   // account for this granularity.
0149   bool compareObjCInterfaceSymbols(const Record *R, SymbolContext &SymCtx,
0150                                    const ObjCInterfaceRecord *DR);
0151 
0152   /// Validate availability annotations against dylib.
0153   Result compareAvailability(const Record *R, SymbolContext &SymCtx,
0154                              const Record *DR);
0155 
0156   /// Compare and validate matching symbol flags.
0157   bool compareSymbolFlags(const Record *R, SymbolContext &SymCtx,
0158                           const Record *DR);
0159 
0160   /// Update result state on each call to `verify`.
0161   void updateState(Result State);
0162 
0163   /// Add verified exported symbol.
0164   void addSymbol(const Record *R, SymbolContext &SymCtx,
0165                  TargetList &&Targets = {});
0166 
0167   /// Find matching dylib slice for target triple that is being parsed.
0168   void assignSlice(const Target &T);
0169 
0170   /// Shared implementation for verifying exported symbols in dylib.
0171   void visitSymbolInDylib(const Record &R, SymbolContext &SymCtx);
0172 
0173   void visitGlobal(const GlobalRecord &R) override;
0174   void visitObjCInterface(const ObjCInterfaceRecord &R) override;
0175   void visitObjCCategory(const ObjCCategoryRecord &R) override;
0176   void visitObjCIVar(const ObjCIVarRecord &R, const StringRef Super);
0177 
0178   /// Gather annotations for symbol for error reporting.
0179   std::string getAnnotatedName(const Record *R, SymbolContext &SymCtx,
0180                                bool ValidSourceLoc = true);
0181 
0182   /// Extract source location for symbol implementations.
0183   /// As this is a relatively expensive operation, it is only used
0184   /// when there is a violation to report and there is not a known declaration
0185   /// in the interface.
0186   void accumulateSrcLocForDylibSymbols();
0187 
0188   // Symbols in dylib.
0189   llvm::MachO::Records Dylib;
0190 
0191   // Reexported interfaces apart of the library.
0192   ReexportedInterfaces Reexports;
0193 
0194   // Symbol aliases.
0195   AliasMap Aliases;
0196 
0197   // Controls what class of violations to report.
0198   VerificationMode Mode = VerificationMode::Invalid;
0199 
0200   // Library is zippered.
0201   bool Zippered = false;
0202 
0203   // Attempt to demangle when reporting violations.
0204   bool Demangle = false;
0205 
0206   // File path to DSYM file.
0207   StringRef DSYMPath;
0208 
0209   // Valid symbols in final text file.
0210   std::unique_ptr<SymbolSet> Exports = std::make_unique<SymbolSet>();
0211 
0212   // Unavailable or obsoleted declarations for a zippered library.
0213   // These are cross referenced against symbols in the dylib.
0214   llvm::StringMap<ZipperedDeclSources> DeferredZipperedSymbols;
0215 
0216   // Track current state of verification while traversing AST.
0217   VerifierContext Ctx;
0218 
0219   // Track DWARF provided source location for dylibs.
0220   DWARFContext *DWARFCtx = nullptr;
0221 
0222   // Source manager for each unique compiler instance.
0223   llvm::SmallVector<IntrusiveRefCntPtr<SourceManager>, 12> SourceManagers;
0224 };
0225 
0226 } // namespace installapi
0227 } // namespace clang
0228 #endif // LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H