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/MapVector.h"
16#include "llvm/ADT/SmallVector.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/StringSet.h"
19#include "llvm/BinaryFormat/MachO.h"
20#include "llvm/Support/CachePruning.h"
21#include "llvm/Support/GlobPattern.h"
22#include "llvm/Support/VersionTuple.h"
23#include "llvm/TextAPI/Architecture.h"
24#include "llvm/TextAPI/Platform.h"
25#include "llvm/TextAPI/Target.h"
26
27#include <vector>
28
29namespace lld {
30namespace macho {
31
32class InputSection;
33class Symbol;
34
35using NamePair = std::pair<llvm::StringRef, llvm::StringRef>;
36using SectionRenameMap = llvm::DenseMap<NamePair, NamePair>;
37using SegmentRenameMap = llvm::DenseMap<llvm::StringRef, llvm::StringRef>;
38
39struct PlatformInfo {
40  llvm::MachO::Target target;
41  llvm::VersionTuple minimum;
42  llvm::VersionTuple sdk;
43};
44
45inline uint32_t encodeVersion(const llvm::VersionTuple &version) {
46  return ((version.getMajor() << 020) |
47          (version.getMinor().value_or(0) << 010) |
48          version.getSubminor().value_or(0));
49}
50
51enum class NamespaceKind {
52  twolevel,
53  flat,
54};
55
56enum class UndefinedSymbolTreatment {
57  unknown,
58  error,
59  warning,
60  suppress,
61  dynamic_lookup,
62};
63
64enum class ICFLevel {
65  unknown,
66  none,
67  safe,
68  all,
69};
70
71enum class ObjCStubsMode {
72  fast,
73  small,
74};
75
76struct SectionAlign {
77  llvm::StringRef segName;
78  llvm::StringRef sectName;
79  uint32_t align;
80};
81
82struct SegmentProtection {
83  llvm::StringRef name;
84  uint32_t maxProt;
85  uint32_t initProt;
86};
87
88class SymbolPatterns {
89public:
90  // GlobPattern can also match literals,
91  // but we prefer the O(1) lookup of DenseSet.
92  llvm::DenseSet<llvm::CachedHashStringRef> literals;
93  std::vector<llvm::GlobPattern> globs;
94
95  bool empty() const { return literals.empty() && globs.empty(); }
96  void clear();
97  void insert(llvm::StringRef symbolName);
98  bool matchLiteral(llvm::StringRef symbolName) const;
99  bool matchGlob(llvm::StringRef symbolName) const;
100  bool match(llvm::StringRef symbolName) const;
101};
102
103enum class SymtabPresence {
104  All,
105  None,
106  SelectivelyIncluded,
107  SelectivelyExcluded,
108};
109
110struct Configuration {
111  Symbol *entry = nullptr;
112  bool hasReexports = false;
113  bool allLoad = false;
114  bool applicationExtension = false;
115  bool archMultiple = false;
116  bool exportDynamic = false;
117  bool forceLoadObjC = false;
118  bool forceLoadSwift = false; // Only applies to LC_LINKER_OPTIONs.
119  bool staticLink = false;
120  bool implicitDylibs = false;
121  bool isPic = false;
122  bool headerPadMaxInstallNames = false;
123  bool markDeadStrippableDylib = false;
124  bool printDylibSearch = false;
125  bool printEachFile = false;
126  bool printWhyLoad = false;
127  bool searchDylibsFirst = false;
128  bool saveTemps = false;
129  bool adhocCodesign = false;
130  bool emitFunctionStarts = false;
131  bool emitBitcodeBundle = false;
132  bool emitDataInCodeInfo = false;
133  bool emitEncryptionInfo = false;
134  bool emitInitOffsets = false;
135  bool emitChainedFixups = false;
136  bool thinLTOEmitImportsFiles;
137  bool thinLTOEmitIndexFiles;
138  bool thinLTOIndexOnly;
139  bool timeTraceEnabled = false;
140  bool dataConst = false;
141  bool dedupStrings = true;
142  bool deadStripDuplicates = false;
143  bool omitDebugInfo = false;
144  bool warnDylibInstallName = false;
145  bool ignoreOptimizationHints = false;
146  bool forceExactCpuSubtypeMatch = false;
147  uint32_t headerPad;
148  uint32_t dylibCompatibilityVersion = 0;
149  uint32_t dylibCurrentVersion = 0;
150  uint32_t timeTraceGranularity = 500;
151  unsigned optimize;
152  std::string progName;
153
154  // For `clang -arch arm64 -arch x86_64`, clang will:
155  // 1. invoke the linker twice, to write one temporary output per arch
156  // 2. invoke `lipo` to merge the two outputs into a single file
157  // `outputFile` is the name of the temporary file the linker writes to.
158  // `finalOutput `is the name of the file lipo writes to after the link.
159  llvm::StringRef outputFile;
160  llvm::StringRef finalOutput;
161
162  llvm::StringRef installName;
163  llvm::StringRef mapFile;
164  llvm::StringRef ltoObjPath;
165  llvm::StringRef thinLTOJobs;
166  llvm::StringRef umbrella;
167  uint32_t ltoo = 2;
168  llvm::CachePruningPolicy thinLTOCachePolicy;
169  llvm::StringRef thinLTOCacheDir;
170  llvm::StringRef thinLTOIndexOnlyArg;
171  std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
172  std::pair<llvm::StringRef, llvm::StringRef> thinLTOPrefixReplace;
173  bool deadStripDylibs = false;
174  bool demangle = false;
175  bool deadStrip = false;
176  bool errorForArchMismatch = false;
177  bool ignoreAutoLink = false;
178  // ld64 allows invalid auto link options as long as the link succeeds. LLD
179  // does not, but there are cases in the wild where the invalid linker options
180  // exist. This allows users to ignore the specific invalid options in the case
181  // they can't easily fix them.
182  llvm::StringSet<> ignoreAutoLinkOptions;
183  bool strictAutoLink = false;
184  PlatformInfo platformInfo;
185  std::optional<PlatformInfo> secondaryPlatformInfo;
186  NamespaceKind namespaceKind = NamespaceKind::twolevel;
187  UndefinedSymbolTreatment undefinedSymbolTreatment =
188      UndefinedSymbolTreatment::error;
189  ICFLevel icfLevel = ICFLevel::none;
190  ObjCStubsMode objcStubsMode = ObjCStubsMode::fast;
191  llvm::MachO::HeaderFileType outputType;
192  std::vector<llvm::StringRef> systemLibraryRoots;
193  std::vector<llvm::StringRef> librarySearchPaths;
194  std::vector<llvm::StringRef> frameworkSearchPaths;
195  llvm::SmallVector<llvm::StringRef, 0> runtimePaths;
196  std::vector<std::string> astPaths;
197  std::vector<Symbol *> explicitUndefineds;
198  llvm::StringSet<> explicitDynamicLookups;
199  // There are typically few custom sectionAlignments or segmentProtections,
200  // so use a vector instead of a map.
201  std::vector<SectionAlign> sectionAlignments;
202  std::vector<SegmentProtection> segmentProtections;
203
204  bool callGraphProfileSort = false;
205  llvm::StringRef printSymbolOrder;
206
207  SectionRenameMap sectionRenameMap;
208  SegmentRenameMap segmentRenameMap;
209
210  bool hasExplicitExports = false;
211  SymbolPatterns exportedSymbols;
212  SymbolPatterns unexportedSymbols;
213  SymbolPatterns whyLive;
214
215  std::vector<std::pair<llvm::StringRef, llvm::StringRef>> aliasedSymbols;
216
217  SymtabPresence localSymbolsPresence = SymtabPresence::All;
218  SymbolPatterns localSymbolPatterns;
219  llvm::SmallVector<llvm::StringRef, 0> mllvmOpts;
220
221  bool zeroModTime = true;
222
223  llvm::StringRef osoPrefix;
224
225  std::vector<llvm::StringRef> dyldEnvs;
226
227  llvm::MachO::Architecture arch() const { return platformInfo.target.Arch; }
228
229  llvm::MachO::PlatformType platform() const {
230    return platformInfo.target.Platform;
231  }
232};
233
234extern std::unique_ptr<Configuration> config;
235
236} // namespace macho
237} // namespace lld
238
239#endif
240