1 //===- Config.h -------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLD_MACHO_CONFIG_H 10 #define LLD_MACHO_CONFIG_H 11 12 #include "llvm/ADT/CachedHashString.h" 13 #include "llvm/ADT/DenseMap.h" 14 #include "llvm/ADT/DenseSet.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/ADT/StringSet.h" 17 #include "llvm/BinaryFormat/MachO.h" 18 #include "llvm/Support/CachePruning.h" 19 #include "llvm/Support/GlobPattern.h" 20 #include "llvm/Support/VersionTuple.h" 21 #include "llvm/TextAPI/Architecture.h" 22 #include "llvm/TextAPI/Platform.h" 23 #include "llvm/TextAPI/Target.h" 24 25 #include <vector> 26 27 namespace lld { 28 namespace macho { 29 30 class Symbol; 31 struct SymbolPriorityEntry; 32 33 using NamePair = std::pair<llvm::StringRef, llvm::StringRef>; 34 using SectionRenameMap = llvm::DenseMap<NamePair, NamePair>; 35 using SegmentRenameMap = llvm::DenseMap<llvm::StringRef, llvm::StringRef>; 36 37 struct PlatformInfo { 38 llvm::MachO::Target target; 39 llvm::VersionTuple minimum; 40 llvm::VersionTuple sdk; 41 }; 42 43 inline uint32_t encodeVersion(const llvm::VersionTuple &version) { 44 return ((version.getMajor() << 020) | 45 (version.getMinor().getValueOr(0) << 010) | 46 version.getSubminor().getValueOr(0)); 47 } 48 49 enum class NamespaceKind { 50 twolevel, 51 flat, 52 }; 53 54 enum class UndefinedSymbolTreatment { 55 unknown, 56 error, 57 warning, 58 suppress, 59 dynamic_lookup, 60 }; 61 62 enum class ICFLevel { 63 unknown, 64 none, 65 safe, 66 all, 67 }; 68 69 struct SectionAlign { 70 llvm::StringRef segName; 71 llvm::StringRef sectName; 72 uint32_t align; 73 }; 74 75 struct SegmentProtection { 76 llvm::StringRef name; 77 uint32_t maxProt; 78 uint32_t initProt; 79 }; 80 81 class SymbolPatterns { 82 public: 83 // GlobPattern can also match literals, 84 // but we prefer the O(1) lookup of DenseSet. 85 llvm::DenseSet<llvm::CachedHashStringRef> literals; 86 std::vector<llvm::GlobPattern> globs; 87 88 bool empty() const { return literals.empty() && globs.empty(); } 89 void clear(); 90 void insert(llvm::StringRef symbolName); 91 bool matchLiteral(llvm::StringRef symbolName) const; 92 bool matchGlob(llvm::StringRef symbolName) const; 93 bool match(llvm::StringRef symbolName) const; 94 }; 95 96 struct Configuration { 97 Symbol *entry = nullptr; 98 bool hasReexports = false; 99 bool allLoad = false; 100 bool applicationExtension = false; 101 bool archMultiple = false; 102 bool exportDynamic = false; 103 bool forceLoadObjC = false; 104 bool forceLoadSwift = false; 105 bool staticLink = false; 106 bool implicitDylibs = false; 107 bool isPic = false; 108 bool headerPadMaxInstallNames = false; 109 bool ltoNewPassManager = LLVM_ENABLE_NEW_PASS_MANAGER; 110 bool markDeadStrippableDylib = false; 111 bool printDylibSearch = false; 112 bool printEachFile = false; 113 bool printWhyLoad = false; 114 bool searchDylibsFirst = false; 115 bool saveTemps = false; 116 bool adhocCodesign = false; 117 bool emitFunctionStarts = false; 118 bool emitBitcodeBundle = false; 119 bool emitDataInCodeInfo = false; 120 bool emitEncryptionInfo = false; 121 bool timeTraceEnabled = false; 122 bool dataConst = false; 123 bool dedupLiterals = true; 124 uint32_t headerPad; 125 uint32_t dylibCompatibilityVersion = 0; 126 uint32_t dylibCurrentVersion = 0; 127 uint32_t timeTraceGranularity = 500; 128 unsigned optimize; 129 std::string progName; 130 131 // For `clang -arch arm64 -arch x86_64`, clang will: 132 // 1. invoke the linker twice, to write one temporary output per arch 133 // 2. invoke `lipo` to merge the two outputs into a single file 134 // `outputFile` is the name of the temporary file the linker writes to. 135 // `finalOutput `is the name of the file lipo writes to after the link. 136 llvm::StringRef outputFile; 137 llvm::StringRef finalOutput; 138 139 llvm::StringRef installName; 140 llvm::StringRef mapFile; 141 llvm::StringRef ltoObjPath; 142 llvm::StringRef thinLTOJobs; 143 llvm::StringRef umbrella; 144 uint32_t ltoo = 2; 145 llvm::CachePruningPolicy thinLTOCachePolicy; 146 llvm::StringRef thinLTOCacheDir; 147 bool deadStripDylibs = false; 148 bool demangle = false; 149 bool deadStrip = false; 150 PlatformInfo platformInfo; 151 NamespaceKind namespaceKind = NamespaceKind::twolevel; 152 UndefinedSymbolTreatment undefinedSymbolTreatment = 153 UndefinedSymbolTreatment::error; 154 ICFLevel icfLevel = ICFLevel::none; 155 llvm::MachO::HeaderFileType outputType; 156 std::vector<llvm::StringRef> systemLibraryRoots; 157 std::vector<llvm::StringRef> librarySearchPaths; 158 std::vector<llvm::StringRef> frameworkSearchPaths; 159 std::vector<llvm::StringRef> runtimePaths; 160 std::vector<std::string> astPaths; 161 std::vector<Symbol *> explicitUndefineds; 162 llvm::StringSet<> explicitDynamicLookups; 163 // There are typically few custom sectionAlignments or segmentProtections, 164 // so use a vector instead of a map. 165 std::vector<SectionAlign> sectionAlignments; 166 std::vector<SegmentProtection> segmentProtections; 167 168 llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities; 169 SectionRenameMap sectionRenameMap; 170 SegmentRenameMap segmentRenameMap; 171 172 SymbolPatterns exportedSymbols; 173 SymbolPatterns unexportedSymbols; 174 175 bool zeroModTime = false; 176 177 llvm::MachO::Architecture arch() const { return platformInfo.target.Arch; } 178 179 llvm::MachO::PlatformKind platform() const { 180 return platformInfo.target.Platform; 181 } 182 }; 183 184 // The symbol with the highest priority should be ordered first in the output 185 // section (modulo input section contiguity constraints). Using priority 186 // (highest first) instead of order (lowest first) has the convenient property 187 // that the default-constructed zero priority -- for symbols/sections without a 188 // user-defined order -- naturally ends up putting them at the end of the 189 // output. 190 struct SymbolPriorityEntry { 191 // The priority given to a matching symbol, regardless of which object file 192 // it originated from. 193 size_t anyObjectFile = 0; 194 // The priority given to a matching symbol from a particular object file. 195 llvm::DenseMap<llvm::StringRef, size_t> objectFiles; 196 }; 197 198 extern Configuration *config; 199 200 } // namespace macho 201 } // namespace lld 202 203 #endif 204