1 | //===- Driver.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_DRIVER_H |
10 | #define LLD_MACHO_DRIVER_H |
11 | |
12 | #include "lld/Common/LLVM.h" |
13 | #include "llvm/ADT/SetVector.h" |
14 | #include "llvm/ADT/StringRef.h" |
15 | #include "llvm/BinaryFormat/MachO.h" |
16 | #include "llvm/Option/OptTable.h" |
17 | #include "llvm/Support/MemoryBuffer.h" |
18 | #include <optional> |
19 | |
20 | #include <set> |
21 | #include <type_traits> |
22 | |
23 | namespace lld { |
24 | class CommonLinkerContext; |
25 | } |
26 | namespace lld::macho { |
27 | |
28 | class DylibFile; |
29 | class InputFile; |
30 | |
31 | class MachOOptTable : public llvm::opt::GenericOptTable { |
32 | public: |
33 | MachOOptTable(); |
34 | llvm::opt::InputArgList parse(CommonLinkerContext &ctx, |
35 | ArrayRef<const char *> argv); |
36 | void printHelp(CommonLinkerContext &ctx, const char *argv0, |
37 | bool showHidden) const; |
38 | }; |
39 | |
40 | // Create enum with OPT_xxx values for each option in Options.td |
41 | enum { |
42 | OPT_INVALID = 0, |
43 | #define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__), |
44 | #include "Options.inc" |
45 | #undef OPTION |
46 | }; |
47 | |
48 | void parseLCLinkerOption(llvm::SmallVectorImpl<StringRef> &LCLinkerOptions, |
49 | InputFile *f, unsigned argc, StringRef data); |
50 | void resolveLCLinkerOptions(); |
51 | |
52 | std::string createResponseFile(const llvm::opt::InputArgList &args); |
53 | |
54 | // Check for both libfoo.dylib and libfoo.tbd (in that order). |
55 | std::optional<StringRef> resolveDylibPath(llvm::StringRef path); |
56 | |
57 | DylibFile *loadDylib(llvm::MemoryBufferRef mbref, DylibFile *umbrella = nullptr, |
58 | bool isBundleLoader = false, |
59 | bool explicitlyLinked = false); |
60 | void resetLoadedDylibs(); |
61 | |
62 | // Search for all possible combinations of `{root}/{name}.{extension}`. |
63 | // If \p extensions are not specified, then just search for `{root}/{name}`. |
64 | std::optional<llvm::StringRef> |
65 | findPathCombination(const llvm::Twine &name, |
66 | const std::vector<llvm::StringRef> &roots, |
67 | ArrayRef<llvm::StringRef> extensions = {"" }); |
68 | |
69 | // If -syslibroot is specified, absolute paths to non-object files may be |
70 | // rerooted. |
71 | llvm::StringRef rerootPath(llvm::StringRef path); |
72 | |
73 | uint32_t getModTime(llvm::StringRef path); |
74 | |
75 | void printArchiveMemberLoad(StringRef reason, const InputFile *); |
76 | |
77 | // Map simulator platforms to their underlying device platform. |
78 | llvm::MachO::PlatformType removeSimulator(llvm::MachO::PlatformType platform); |
79 | |
80 | // Helper class to export dependency info. |
81 | class DependencyTracker { |
82 | public: |
83 | explicit DependencyTracker(llvm::StringRef path); |
84 | |
85 | // Adds the given path to the set of not-found files. |
86 | inline void logFileNotFound(const Twine &path) { |
87 | if (active) |
88 | notFounds.insert(path.str()); |
89 | } |
90 | |
91 | // Writes the dependencies to specified path. The content is first sorted by |
92 | // OpCode and then by the filename (in alphabetical order). |
93 | void write(llvm::StringRef version, |
94 | const llvm::SetVector<InputFile *> &inputs, |
95 | llvm::StringRef output); |
96 | |
97 | private: |
98 | enum DepOpCode : uint8_t { |
99 | // Denotes the linker version. |
100 | Version = 0x00, |
101 | // Denotes the input files. |
102 | Input = 0x10, |
103 | // Denotes the files that do not exist(?) |
104 | NotFound = 0x11, |
105 | // Denotes the output files. |
106 | Output = 0x40, |
107 | }; |
108 | |
109 | const llvm::StringRef path; |
110 | bool active; |
111 | |
112 | // The paths need to be alphabetically ordered. |
113 | // We need to own the paths because some of them are temporarily |
114 | // constructed. |
115 | std::set<std::string> notFounds; |
116 | }; |
117 | |
118 | extern std::unique_ptr<DependencyTracker> depTracker; |
119 | |
120 | } // namespace lld::macho |
121 | |
122 | #endif |
123 | |