annotate lld/MachO/Driver.cpp @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 0572611fdcc8
children 5f17cb93ff66
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 //===- Driver.cpp ---------------------------------------------------------===//
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 #include "Driver.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 #include "Config.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 #include "InputFiles.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
12 #include "LTO.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
13 #include "MarkLive.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
14 #include "ObjC.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 #include "OutputSection.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 #include "OutputSegment.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 #include "SymbolTable.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 #include "Symbols.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
19 #include "SyntheticSections.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 #include "Target.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "Writer.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "lld/Common/Args.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 #include "lld/Common/Driver.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "lld/Common/ErrorHandler.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 #include "lld/Common/LLVM.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 #include "lld/Common/Memory.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
28 #include "lld/Common/Reproduce.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 #include "lld/Common/Version.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 #include "llvm/ADT/DenseSet.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 #include "llvm/ADT/StringExtras.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 #include "llvm/ADT/StringRef.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 #include "llvm/BinaryFormat/MachO.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 #include "llvm/BinaryFormat/Magic.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
35 #include "llvm/Config/llvm-config.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
36 #include "llvm/LTO/LTO.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 #include "llvm/Object/Archive.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 #include "llvm/Option/ArgList.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
39 #include "llvm/Support/CommandLine.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
40 #include "llvm/Support/FileSystem.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
41 #include "llvm/Support/Host.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 #include "llvm/Support/MemoryBuffer.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
43 #include "llvm/Support/Parallel.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 #include "llvm/Support/Path.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
45 #include "llvm/Support/TarWriter.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
46 #include "llvm/Support/TargetSelect.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
47 #include "llvm/Support/TimeProfiler.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
48 #include "llvm/TextAPI/PackedVersion.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
49
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
50 #include <algorithm>
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 using namespace llvm;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 using namespace llvm::MachO;
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
54 using namespace llvm::object;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
55 using namespace llvm::opt;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 using namespace llvm::sys;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 using namespace lld;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 using namespace lld::macho;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
60 Configuration *macho::config;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
61 DependencyTracker *macho::depTracker;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
63 static HeaderFileType getOutputType(const InputArgList &args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
64 // TODO: -r, -dylinker, -preload...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
65 Arg *outputArg = args.getLastArg(OPT_bundle, OPT_dylib, OPT_execute);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
66 if (outputArg == nullptr)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
67 return MH_EXECUTE;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
69 switch (outputArg->getOption().getID()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
70 case OPT_bundle:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
71 return MH_BUNDLE;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
72 case OPT_dylib:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
73 return MH_DYLIB;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
74 case OPT_execute:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
75 return MH_EXECUTE;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
76 default:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
77 llvm_unreachable("internal error");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
78 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
79 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
80
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
81 static Optional<StringRef> findLibrary(StringRef name) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
82 if (config->searchDylibsFirst) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
83 if (Optional<StringRef> path = findPathCombination(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
84 "lib" + name, config->librarySearchPaths, {".tbd", ".dylib"}))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
85 return path;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
86 return findPathCombination("lib" + name, config->librarySearchPaths,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
87 {".a"});
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
88 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
89 return findPathCombination("lib" + name, config->librarySearchPaths,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
90 {".tbd", ".dylib", ".a"});
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
91 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
93 static Optional<std::string> findFramework(StringRef name) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
94 SmallString<260> symlink;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
95 StringRef suffix;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
96 std::tie(name, suffix) = name.split(",");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
97 for (StringRef dir : config->frameworkSearchPaths) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
98 symlink = dir;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
99 path::append(symlink, name + ".framework", name);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
101 if (!suffix.empty()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
102 // NOTE: we must resolve the symlink before trying the suffixes, because
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
103 // there are no symlinks for the suffixed paths.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
104 SmallString<260> location;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
105 if (!fs::real_path(symlink, location)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
106 // only append suffix if realpath() succeeds
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
107 Twine suffixed = location + suffix;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
108 if (fs::exists(suffixed))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
109 return suffixed.str();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
110 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
111 // Suffix lookup failed, fall through to the no-suffix case.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
112 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
114 if (Optional<std::string> path = resolveDylibPath(symlink))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
115 return path;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
116 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
117 return {};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
118 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
120 static bool warnIfNotDirectory(StringRef option, StringRef path) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
121 if (!fs::exists(path)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
122 warn("directory not found for option -" + option + path);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
123 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
124 } else if (!fs::is_directory(path)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
125 warn("option -" + option + path + " references a non-directory path");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
126 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
127 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
128 return true;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
131 static std::vector<StringRef>
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
132 getSearchPaths(unsigned optionCode, InputArgList &args,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
133 const std::vector<StringRef> &roots,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
134 const SmallVector<StringRef, 2> &systemPaths) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
135 std::vector<StringRef> paths;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
136 StringRef optionLetter{optionCode == OPT_F ? "F" : "L"};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
137 for (StringRef path : args::getStrings(args, optionCode)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
138 // NOTE: only absolute paths are re-rooted to syslibroot(s)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
139 bool found = false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
140 if (path::is_absolute(path, path::Style::posix)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
141 for (StringRef root : roots) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
142 SmallString<261> buffer(root);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
143 path::append(buffer, path);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
144 // Do not warn about paths that are computed via the syslib roots
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
145 if (fs::is_directory(buffer)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
146 paths.push_back(saver.save(buffer.str()));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
147 found = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
148 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
149 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
150 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
151 if (!found && warnIfNotDirectory(optionLetter, path))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
152 paths.push_back(path);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
154
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
155 // `-Z` suppresses the standard "system" search paths.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
156 if (args.hasArg(OPT_Z))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
157 return paths;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
158
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
159 for (const StringRef &path : systemPaths) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
160 for (const StringRef &root : roots) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
161 SmallString<261> buffer(root);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
162 path::append(buffer, path);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
163 if (fs::is_directory(buffer))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
164 paths.push_back(saver.save(buffer.str()));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
165 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
166 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
167 return paths;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
168 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
169
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
170 static std::vector<StringRef> getSystemLibraryRoots(InputArgList &args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
171 std::vector<StringRef> roots;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
172 for (const Arg *arg : args.filtered(OPT_syslibroot))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
173 roots.push_back(arg->getValue());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
174 // NOTE: the final `-syslibroot` being `/` will ignore all roots
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
175 if (roots.size() && roots.back() == "/")
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
176 roots.clear();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
177 // NOTE: roots can never be empty - add an empty root to simplify the library
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
178 // and framework search path computation.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
179 if (roots.empty())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
180 roots.emplace_back("");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
181 return roots;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
182 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
183
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
184 static std::vector<StringRef>
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
185 getLibrarySearchPaths(InputArgList &args, const std::vector<StringRef> &roots) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
186 return getSearchPaths(OPT_L, args, roots, {"/usr/lib", "/usr/local/lib"});
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
188
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
189 static std::vector<StringRef>
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
190 getFrameworkSearchPaths(InputArgList &args,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
191 const std::vector<StringRef> &roots) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
192 return getSearchPaths(OPT_F, args, roots,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
193 {"/Library/Frameworks", "/System/Library/Frameworks"});
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
196 namespace {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
197 struct ArchiveMember {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
198 MemoryBufferRef mbref;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
199 uint32_t modTime;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
200 };
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
201 } // namespace
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
202
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
203 // Returns slices of MB by parsing MB as an archive file.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
204 // Each slice consists of a member file in the archive.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
205 static std::vector<ArchiveMember> getArchiveMembers(MemoryBufferRef mb) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
206 std::unique_ptr<Archive> file =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
207 CHECK(Archive::create(mb),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
208 mb.getBufferIdentifier() + ": failed to parse archive");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
209 Archive *archive = file.get();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
210 make<std::unique_ptr<Archive>>(std::move(file)); // take ownership
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
211
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
212 std::vector<ArchiveMember> v;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
213 Error err = Error::success();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
214
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
215 // Thin archives refer to .o files, so --reproduce needs the .o files too.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
216 bool addToTar = archive->isThin() && tar;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
217
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
218 for (const Archive::Child &c : archive->children(err)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
219 MemoryBufferRef mbref =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
220 CHECK(c.getMemoryBufferRef(),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
221 mb.getBufferIdentifier() +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
222 ": could not get the buffer for a child of the archive");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
223 if (addToTar)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
224 tar->append(relativeToRoot(check(c.getFullName())), mbref.getBuffer());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
225 uint32_t modTime = toTimeT(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
226 CHECK(c.getLastModified(), mb.getBufferIdentifier() +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
227 ": could not get the modification "
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
228 "time for a child of the archive"));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
229 v.push_back({mbref, modTime});
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
231 if (err)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
232 fatal(mb.getBufferIdentifier() +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
233 ": Archive::children failed: " + toString(std::move(err)));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
234
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
235 return v;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
237
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
238 static InputFile *addFile(StringRef path, bool forceLoadArchive,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
239 bool isExplicit = true,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
240 bool isBundleLoader = false) {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 Optional<MemoryBufferRef> buffer = readFile(path);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 if (!buffer)
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
243 return nullptr;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 MemoryBufferRef mbref = *buffer;
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
245 InputFile *newFile = nullptr;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
246
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
247 file_magic magic = identify_magic(mbref.getBuffer());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
248 switch (magic) {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 case file_magic::archive: {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 std::unique_ptr<object::Archive> file = CHECK(
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 object::Archive::create(mbref), path + ": failed to parse archive");
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 if (!file->isEmpty() && !file->hasSymbolTable())
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 error(path + ": archive has no index; run ranlib to add one");
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
255
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
256 if (config->allLoad || forceLoadArchive) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
257 if (Optional<MemoryBufferRef> buffer = readFile(path)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
258 for (const ArchiveMember &member : getArchiveMembers(*buffer)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
259 if (Optional<InputFile *> file = loadArchiveMember(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
260 member.mbref, member.modTime, path, /*objCOnly=*/false)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
261 inputFiles.insert(*file);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
262 printArchiveMemberLoad(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
263 (forceLoadArchive ? "-force_load" : "-all_load"),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
264 inputFiles.back());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
265 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
266 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
267 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
268 } else if (config->forceLoadObjC) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
269 for (const object::Archive::Symbol &sym : file->symbols())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
270 if (sym.getName().startswith(objc::klass))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
271 symtab->addUndefined(sym.getName(), /*file=*/nullptr,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
272 /*isWeakRef=*/false);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
273
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
274 // TODO: no need to look for ObjC sections for a given archive member if
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
275 // we already found that it contains an ObjC symbol. We should also
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
276 // consider creating a LazyObjFile class in order to avoid double-loading
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
277 // these files here and below (as part of the ArchiveFile).
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
278 if (Optional<MemoryBufferRef> buffer = readFile(path)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
279 for (const ArchiveMember &member : getArchiveMembers(*buffer)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
280 if (Optional<InputFile *> file = loadArchiveMember(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
281 member.mbref, member.modTime, path, /*objCOnly=*/true)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
282 inputFiles.insert(*file);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
283 printArchiveMemberLoad("-ObjC", inputFiles.back());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
284 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
285 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
286 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
287 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
288
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
289 newFile = make<ArchiveFile>(std::move(file));
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 break;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 case file_magic::macho_object:
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
293 newFile = make<ObjFile>(mbref, getModTime(path), "");
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 break;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 case file_magic::macho_dynamically_linked_shared_lib:
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
296 case file_magic::macho_dynamically_linked_shared_lib_stub:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
297 case file_magic::tapi_file:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
298 if (DylibFile * dylibFile = loadDylib(mbref)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
299 if (isExplicit)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
300 dylibFile->explicitlyLinked = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
301 newFile = dylibFile;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
302 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
303 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
304 case file_magic::bitcode:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
305 newFile = make<BitcodeFile>(mbref);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
306 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
307 case file_magic::macho_executable:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
308 case file_magic::macho_bundle:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
309 // We only allow executable and bundle type here if it is used
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
310 // as a bundle loader.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
311 if (!isBundleLoader)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
312 error(path + ": unhandled file type");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
313 if (DylibFile *dylibFile = loadDylib(mbref, nullptr, isBundleLoader))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
314 newFile = dylibFile;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 break;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 default:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 error(path + ": unhandled file type");
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
319 if (newFile) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
320 // printArchiveMemberLoad() prints both .a and .o names, so no need to
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
321 // print the .a name here.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
322 if (config->printEachFile && magic != file_magic::archive &&
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
323 !isa<DylibFile>(newFile))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
324 message(toString(newFile));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
325 inputFiles.insert(newFile);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
326 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
327 return newFile;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
328 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
329
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
330 static void addLibrary(StringRef name, bool isNeeded, bool isWeak,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
331 bool isReexport, bool isExplicit) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
332 if (Optional<StringRef> path = findLibrary(name)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
333 if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
334 addFile(*path, /*forceLoadArchive=*/false, isExplicit))) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
335 if (isNeeded)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
336 dylibFile->forceNeeded = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
337 if (isWeak)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
338 dylibFile->forceWeakImport = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
339 if (isReexport) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
340 config->hasReexports = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
341 dylibFile->reexport = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
342 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
343 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
344 return;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
345 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
346 error("library not found for -l" + name);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
348
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
349 static void addFramework(StringRef name, bool isNeeded, bool isWeak,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
350 bool isReexport, bool isExplicit) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
351 if (Optional<std::string> path = findFramework(name)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
352 if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
353 addFile(*path, /*forceLoadArchive=*/false, isExplicit))) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
354 if (isNeeded)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
355 dylibFile->forceNeeded = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
356 if (isWeak)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
357 dylibFile->forceWeakImport = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
358 if (isReexport) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
359 config->hasReexports = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
360 dylibFile->reexport = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
361 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
362 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
363 return;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
364 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
365 error("framework not found for -framework " + name);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
366 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
367
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
368 // Parses LC_LINKER_OPTION contents, which can add additional command line
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
369 // flags.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
370 void macho::parseLCLinkerOption(InputFile *f, unsigned argc, StringRef data) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
371 SmallVector<const char *, 4> argv;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
372 size_t offset = 0;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
373 for (unsigned i = 0; i < argc && offset < data.size(); ++i) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
374 argv.push_back(data.data() + offset);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
375 offset += strlen(data.data() + offset) + 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
376 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
377 if (argv.size() != argc || offset > data.size())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
378 fatal(toString(f) + ": invalid LC_LINKER_OPTION");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
379
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
380 MachOOptTable table;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
381 unsigned missingIndex, missingCount;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
382 InputArgList args = table.ParseArgs(argv, missingIndex, missingCount);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
383 if (missingCount)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
384 fatal(Twine(args.getArgString(missingIndex)) + ": missing argument");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
385 for (const Arg *arg : args.filtered(OPT_UNKNOWN))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
386 error("unknown argument: " + arg->getAsString(args));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
387
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
388 for (const Arg *arg : args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
389 switch (arg->getOption().getID()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
390 case OPT_l:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
391 addLibrary(arg->getValue(), /*isNeeded=*/false, /*isWeak=*/false,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
392 /*isReexport=*/false, /*isExplicit=*/false);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
393 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
394 case OPT_framework:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
395 addFramework(arg->getValue(), /*isNeeded=*/false, /*isWeak=*/false,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
396 /*isReexport=*/false, /*isExplicit=*/false);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
397 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
398 default:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
399 error(arg->getSpelling() + " is not allowed in LC_LINKER_OPTION");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
400 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
401 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
402 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
403
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
404 static void addFileList(StringRef path) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
405 Optional<MemoryBufferRef> buffer = readFile(path);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
406 if (!buffer)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
407 return;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
408 MemoryBufferRef mbref = *buffer;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
409 for (StringRef path : args::getLines(mbref))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
410 addFile(rerootPath(path), /*forceLoadArchive=*/false);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
412
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 // An order file has one entry per line, in the following format:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 //
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
415 // <cpu>:<object file>:<symbol name>
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
416 //
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
417 // <cpu> and <object file> are optional. If not specified, then that entry
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
418 // matches any symbol of that name. Parsing this format is not quite
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
419 // straightforward because the symbol name itself can contain colons, so when
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
420 // encountering a colon, we consider the preceding characters to decide if it
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
421 // can be a valid CPU type or file path.
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 // If a symbol is matched by multiple entries, then it takes the lowest-ordered
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 // entry (the one nearest to the front of the list.)
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
426 // The file can also have line comments that start with '#'.
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
427 static void parseOrderFile(StringRef path) {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
428 Optional<MemoryBufferRef> buffer = readFile(path);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
429 if (!buffer) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 error("Could not read order file at " + path);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 return;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
433
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 MemoryBufferRef mbref = *buffer;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 size_t priority = std::numeric_limits<size_t>::max();
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
436 for (StringRef line : args::getLines(mbref)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
437 StringRef objectFile, symbol;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
438 line = line.take_until([](char c) { return c == '#'; }); // ignore comments
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
439 line = line.ltrim();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
440
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
441 CPUType cpuType = StringSwitch<CPUType>(line)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
442 .StartsWith("i386:", CPU_TYPE_I386)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
443 .StartsWith("x86_64:", CPU_TYPE_X86_64)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
444 .StartsWith("arm:", CPU_TYPE_ARM)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
445 .StartsWith("arm64:", CPU_TYPE_ARM64)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
446 .StartsWith("ppc:", CPU_TYPE_POWERPC)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
447 .StartsWith("ppc64:", CPU_TYPE_POWERPC64)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
448 .Default(CPU_TYPE_ANY);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
449
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
450 if (cpuType != CPU_TYPE_ANY && cpuType != target->cpuType)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
451 continue;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
452
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
453 // Drop the CPU type as well as the colon
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
454 if (cpuType != CPU_TYPE_ANY)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
455 line = line.drop_until([](char c) { return c == ':'; }).drop_front();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
456
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
457 constexpr std::array<StringRef, 2> fileEnds = {".o:", ".o):"};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
458 for (StringRef fileEnd : fileEnds) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
459 size_t pos = line.find(fileEnd);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
460 if (pos != StringRef::npos) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
461 // Split the string around the colon
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
462 objectFile = line.take_front(pos + fileEnd.size() - 1);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
463 line = line.drop_front(pos + fileEnd.size());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
464 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
465 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
467 symbol = line.trim();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
468
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 if (!symbol.empty()) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
470 SymbolPriorityEntry &entry = config->priorities[symbol];
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 if (!objectFile.empty())
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 entry.objectFiles.insert(std::make_pair(objectFile, priority));
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 else
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 entry.anyObjectFile = std::max(entry.anyObjectFile, priority);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
476
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 --priority;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
479 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
480
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
481 // We expect sub-library names of the form "libfoo", which will match a dylib
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
482 // with a path of .*/libfoo.{dylib, tbd}.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
483 // XXX ld64 seems to ignore the extension entirely when matching sub-libraries;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
484 // I'm not sure what the use case for that is.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
485 static bool markReexport(StringRef searchName, ArrayRef<StringRef> extensions) {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 for (InputFile *file : inputFiles) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 StringRef filename = path::filename(dylibFile->getName());
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
489 if (filename.consume_front(searchName) &&
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
490 (filename.empty() ||
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
491 find(extensions, filename) != extensions.end())) {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 dylibFile->reexport = true;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 return true;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
495 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
496 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 return false;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
499
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
500 // This function is called on startup. We need this for LTO since
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
501 // LTO calls LLVM functions to compile bitcode files to native code.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
502 // Technically this can be delayed until we read bitcode files, but
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
503 // we don't bother to do lazily because the initialization is fast.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
504 static void initLLVM() {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
505 InitializeAllTargets();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
506 InitializeAllTargetMCs();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
507 InitializeAllAsmPrinters();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
508 InitializeAllAsmParsers();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
509 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
510
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
511 static void compileBitcodeFiles() {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
512 TimeTraceScope timeScope("LTO");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
513 auto *lto = make<BitcodeCompiler>();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
514 for (InputFile *file : inputFiles)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
515 if (auto *bitcodeFile = dyn_cast<BitcodeFile>(file))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
516 lto->add(*bitcodeFile);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
517
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
518 for (ObjFile *file : lto->compile())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
519 inputFiles.insert(file);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
520 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
521
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
522 // Replaces common symbols with defined symbols residing in __common sections.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
523 // This function must be called after all symbol names are resolved (i.e. after
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
524 // all InputFiles have been loaded.) As a result, later operations won't see
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
525 // any CommonSymbols.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
526 static void replaceCommonSymbols() {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
527 TimeTraceScope timeScope("Replace common symbols");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
528 for (Symbol *sym : symtab->getSymbols()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
529 auto *common = dyn_cast<CommonSymbol>(sym);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
530 if (common == nullptr)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
531 continue;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
532
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
533 auto *isec = make<InputSection>();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
534 isec->file = common->getFile();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
535 isec->name = section_names::common;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
536 isec->segname = segment_names::data;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
537 isec->align = common->align;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
538 // Casting to size_t will truncate large values on 32-bit architectures,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
539 // but it's not really worth supporting the linking of 64-bit programs on
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
540 // 32-bit archs.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
541 isec->data = {nullptr, static_cast<size_t>(common->size)};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
542 isec->flags = S_ZEROFILL;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
543 inputSections.push_back(isec);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
544
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
545 // FIXME: CommonSymbol should store isReferencedDynamically, noDeadStrip
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
546 // and pass them on here.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
547 replaceSymbol<Defined>(sym, sym->getName(), isec->file, isec, /*value=*/0,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
548 /*size=*/0,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
549 /*isWeakDef=*/false,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
550 /*isExternal=*/true, common->privateExtern,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
551 /*isThumb=*/false,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
552 /*isReferencedDynamically=*/false,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
553 /*noDeadStrip=*/false);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
554 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
555 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
556
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
557 static void initializeSectionRenameMap() {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
558 if (config->dataConst) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
559 SmallVector<StringRef> v{section_names::got,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
560 section_names::authGot,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
561 section_names::authPtr,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
562 section_names::nonLazySymbolPtr,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
563 section_names::const_,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
564 section_names::cfString,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
565 section_names::moduleInitFunc,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
566 section_names::moduleTermFunc,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
567 section_names::objcClassList,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
568 section_names::objcNonLazyClassList,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
569 section_names::objcCatList,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
570 section_names::objcNonLazyCatList,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
571 section_names::objcProtoList,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
572 section_names::objcImageInfo};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
573 for (StringRef s : v)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
574 config->sectionRenameMap[{segment_names::data, s}] = {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
575 segment_names::dataConst, s};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
576 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
577 config->sectionRenameMap[{segment_names::text, section_names::staticInit}] = {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
578 segment_names::text, section_names::text};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
579 config->sectionRenameMap[{segment_names::import, section_names::pointers}] = {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
580 config->dataConst ? segment_names::dataConst : segment_names::data,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
581 section_names::nonLazySymbolPtr};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
582 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
583
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
584 static inline char toLowerDash(char x) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
585 if (x >= 'A' && x <= 'Z')
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
586 return x - 'A' + 'a';
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
587 else if (x == ' ')
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
588 return '-';
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
589 return x;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
590 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
591
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
592 static std::string lowerDash(StringRef s) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
593 return std::string(map_iterator(s.begin(), toLowerDash),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
594 map_iterator(s.end(), toLowerDash));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
595 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
596
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
597 // Has the side-effect of setting Config::platformInfo.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
598 static PlatformKind parsePlatformVersion(const ArgList &args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
599 const Arg *arg = args.getLastArg(OPT_platform_version);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
600 if (!arg) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
601 error("must specify -platform_version");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
602 return PlatformKind::unknown;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
603 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
604
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
605 StringRef platformStr = arg->getValue(0);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
606 StringRef minVersionStr = arg->getValue(1);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
607 StringRef sdkVersionStr = arg->getValue(2);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
608
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
609 // TODO(compnerd) see if we can generate this case list via XMACROS
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
610 PlatformKind platform =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
611 StringSwitch<PlatformKind>(lowerDash(platformStr))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
612 .Cases("macos", "1", PlatformKind::macOS)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
613 .Cases("ios", "2", PlatformKind::iOS)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
614 .Cases("tvos", "3", PlatformKind::tvOS)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
615 .Cases("watchos", "4", PlatformKind::watchOS)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
616 .Cases("bridgeos", "5", PlatformKind::bridgeOS)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
617 .Cases("mac-catalyst", "6", PlatformKind::macCatalyst)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
618 .Cases("ios-simulator", "7", PlatformKind::iOSSimulator)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
619 .Cases("tvos-simulator", "8", PlatformKind::tvOSSimulator)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
620 .Cases("watchos-simulator", "9", PlatformKind::watchOSSimulator)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
621 .Cases("driverkit", "10", PlatformKind::driverKit)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
622 .Default(PlatformKind::unknown);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
623 if (platform == PlatformKind::unknown)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
624 error(Twine("malformed platform: ") + platformStr);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
625 // TODO: check validity of version strings, which varies by platform
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
626 // NOTE: ld64 accepts version strings with 5 components
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
627 // llvm::VersionTuple accepts no more than 4 components
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
628 // Has Apple ever published version strings with 5 components?
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
629 if (config->platformInfo.minimum.tryParse(minVersionStr))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
630 error(Twine("malformed minimum version: ") + minVersionStr);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
631 if (config->platformInfo.sdk.tryParse(sdkVersionStr))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
632 error(Twine("malformed sdk version: ") + sdkVersionStr);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
633 return platform;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
634 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
635
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
636 // Has the side-effect of setting Config::target.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
637 static TargetInfo *createTargetInfo(InputArgList &args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
638 StringRef archName = args.getLastArgValue(OPT_arch);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
639 if (archName.empty())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
640 fatal("must specify -arch");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
641 PlatformKind platform = parsePlatformVersion(args);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
642
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
643 config->platformInfo.target =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
644 MachO::Target(getArchitectureFromName(archName), platform);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
645
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
646 uint32_t cpuType;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
647 uint32_t cpuSubtype;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
648 std::tie(cpuType, cpuSubtype) = getCPUTypeFromArchitecture(config->arch());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
649
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
650 switch (cpuType) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
651 case CPU_TYPE_X86_64:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
652 return createX86_64TargetInfo();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
653 case CPU_TYPE_ARM64:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
654 return createARM64TargetInfo();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
655 case CPU_TYPE_ARM64_32:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
656 return createARM64_32TargetInfo();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
657 case CPU_TYPE_ARM:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
658 return createARMTargetInfo(cpuSubtype);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
659 default:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
660 fatal("missing or unsupported -arch " + archName);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
661 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
662 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
663
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
664 static UndefinedSymbolTreatment
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
665 getUndefinedSymbolTreatment(const ArgList &args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
666 StringRef treatmentStr = args.getLastArgValue(OPT_undefined);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
667 auto treatment =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
668 StringSwitch<UndefinedSymbolTreatment>(treatmentStr)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
669 .Cases("error", "", UndefinedSymbolTreatment::error)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
670 .Case("warning", UndefinedSymbolTreatment::warning)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
671 .Case("suppress", UndefinedSymbolTreatment::suppress)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
672 .Case("dynamic_lookup", UndefinedSymbolTreatment::dynamic_lookup)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
673 .Default(UndefinedSymbolTreatment::unknown);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
674 if (treatment == UndefinedSymbolTreatment::unknown) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
675 warn(Twine("unknown -undefined TREATMENT '") + treatmentStr +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
676 "', defaulting to 'error'");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
677 treatment = UndefinedSymbolTreatment::error;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
678 } else if (config->namespaceKind == NamespaceKind::twolevel &&
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
679 (treatment == UndefinedSymbolTreatment::warning ||
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
680 treatment == UndefinedSymbolTreatment::suppress)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
681 if (treatment == UndefinedSymbolTreatment::warning)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
682 error("'-undefined warning' only valid with '-flat_namespace'");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
683 else
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
684 error("'-undefined suppress' only valid with '-flat_namespace'");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
685 treatment = UndefinedSymbolTreatment::error;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
686 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
687 return treatment;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
688 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
689
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
690 static void warnIfDeprecatedOption(const Option &opt) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
691 if (!opt.getGroup().isValid())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
692 return;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
693 if (opt.getGroup().getID() == OPT_grp_deprecated) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
694 warn("Option `" + opt.getPrefixedName() + "' is deprecated in ld64:");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
695 warn(opt.getHelpText());
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
696 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
697 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
698
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
699 static void warnIfUnimplementedOption(const Option &opt) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
700 if (!opt.getGroup().isValid() || !opt.hasFlag(DriverFlag::HelpHidden))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
701 return;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
702 switch (opt.getGroup().getID()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
703 case OPT_grp_deprecated:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
704 // warn about deprecated options elsewhere
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
705 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
706 case OPT_grp_undocumented:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
707 warn("Option `" + opt.getPrefixedName() +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
708 "' is undocumented. Should lld implement it?");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
709 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
710 case OPT_grp_obsolete:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
711 warn("Option `" + opt.getPrefixedName() +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
712 "' is obsolete. Please modernize your usage.");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
713 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
714 case OPT_grp_ignored:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
715 warn("Option `" + opt.getPrefixedName() + "' is ignored.");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
716 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
717 default:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
718 warn("Option `" + opt.getPrefixedName() +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
719 "' is not yet implemented. Stay tuned...");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
720 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
721 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
722 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
723
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
724 static const char *getReproduceOption(InputArgList &args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
725 if (const Arg *arg = args.getLastArg(OPT_reproduce))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
726 return arg->getValue();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
727 return getenv("LLD_REPRODUCE");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
728 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
729
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
730 static void parseClangOption(StringRef opt, const Twine &msg) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
731 std::string err;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
732 raw_string_ostream os(err);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
733
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
734 const char *argv[] = {"lld", opt.data()};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
735 if (cl::ParseCommandLineOptions(2, argv, "", &os))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
736 return;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
737 os.flush();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
738 error(msg + ": " + StringRef(err).trim());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
739 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
740
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
741 static uint32_t parseDylibVersion(const ArgList &args, unsigned id) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
742 const Arg *arg = args.getLastArg(id);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
743 if (!arg)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
744 return 0;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
745
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
746 if (config->outputType != MH_DYLIB) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
747 error(arg->getAsString(args) + ": only valid with -dylib");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
748 return 0;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
749 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
750
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
751 PackedVersion version;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
752 if (!version.parse32(arg->getValue())) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
753 error(arg->getAsString(args) + ": malformed version");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
754 return 0;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
755 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
756
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
757 return version.rawValue();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
758 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
759
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
760 static uint32_t parseProtection(StringRef protStr) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
761 uint32_t prot = 0;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
762 for (char c : protStr) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
763 switch (c) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
764 case 'r':
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
765 prot |= VM_PROT_READ;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
766 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
767 case 'w':
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
768 prot |= VM_PROT_WRITE;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
769 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
770 case 'x':
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
771 prot |= VM_PROT_EXECUTE;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
772 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
773 case '-':
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
774 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
775 default:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
776 error("unknown -segprot letter '" + Twine(c) + "' in " + protStr);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
777 return 0;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
778 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
779 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
780 return prot;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
781 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
782
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
783 static std::vector<SectionAlign> parseSectAlign(const opt::InputArgList &args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
784 std::vector<SectionAlign> sectAligns;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
785 for (const Arg *arg : args.filtered(OPT_sectalign)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
786 StringRef segName = arg->getValue(0);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
787 StringRef sectName = arg->getValue(1);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
788 StringRef alignStr = arg->getValue(2);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
789 if (alignStr.startswith("0x") || alignStr.startswith("0X"))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
790 alignStr = alignStr.drop_front(2);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
791 uint32_t align;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
792 if (alignStr.getAsInteger(16, align)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
793 error("-sectalign: failed to parse '" + StringRef(arg->getValue(2)) +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
794 "' as number");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
795 continue;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
796 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
797 if (!isPowerOf2_32(align)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
798 error("-sectalign: '" + StringRef(arg->getValue(2)) +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
799 "' (in base 16) not a power of two");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
800 continue;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
801 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
802 sectAligns.push_back({segName, sectName, align});
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
803 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
804 return sectAligns;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
805 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
806
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
807 static bool dataConstDefault(const InputArgList &args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
808 switch (config->outputType) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
809 case MH_EXECUTE:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
810 return !args.hasArg(OPT_no_pie);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
811 case MH_BUNDLE:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
812 // FIXME: return false when -final_name ...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
813 // has prefix "/System/Library/UserEventPlugins/"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
814 // or matches "/usr/libexec/locationd" "/usr/libexec/terminusd"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
815 return true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
816 case MH_DYLIB:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
817 return true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
818 case MH_OBJECT:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
819 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
820 default:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
821 llvm_unreachable(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
822 "unsupported output type for determining data-const default");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
823 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
824 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
825 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
826
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
827 void SymbolPatterns::clear() {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
828 literals.clear();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
829 globs.clear();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
830 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
831
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
832 void SymbolPatterns::insert(StringRef symbolName) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
833 if (symbolName.find_first_of("*?[]") == StringRef::npos)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
834 literals.insert(CachedHashStringRef(symbolName));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
835 else if (Expected<GlobPattern> pattern = GlobPattern::create(symbolName))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
836 globs.emplace_back(*pattern);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
837 else
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
838 error("invalid symbol-name pattern: " + symbolName);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
839 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
840
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
841 bool SymbolPatterns::matchLiteral(StringRef symbolName) const {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
842 return literals.contains(CachedHashStringRef(symbolName));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
843 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
844
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
845 bool SymbolPatterns::matchGlob(StringRef symbolName) const {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
846 for (const llvm::GlobPattern &glob : globs)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
847 if (glob.match(symbolName))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
848 return true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
849 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
850 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
851
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
852 bool SymbolPatterns::match(StringRef symbolName) const {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
853 return matchLiteral(symbolName) || matchGlob(symbolName);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
854 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
855
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
856 static void handleSymbolPatterns(InputArgList &args,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
857 SymbolPatterns &symbolPatterns,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
858 unsigned singleOptionCode,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
859 unsigned listFileOptionCode) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
860 for (const Arg *arg : args.filtered(singleOptionCode))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
861 symbolPatterns.insert(arg->getValue());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
862 for (const Arg *arg : args.filtered(listFileOptionCode)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
863 StringRef path = arg->getValue();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
864 Optional<MemoryBufferRef> buffer = readFile(path);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
865 if (!buffer) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
866 error("Could not read symbol file: " + path);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
867 continue;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
868 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
869 MemoryBufferRef mbref = *buffer;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
870 for (StringRef line : args::getLines(mbref)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
871 line = line.take_until([](char c) { return c == '#'; }).trim();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
872 if (!line.empty())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
873 symbolPatterns.insert(line);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
874 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
875 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
876 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
877
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
878 void createFiles(const InputArgList &args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
879 TimeTraceScope timeScope("Load input files");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
880 // This loop should be reserved for options whose exact ordering matters.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
881 // Other options should be handled via filtered() and/or getLastArg().
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
882 for (const Arg *arg : args) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
883 const Option &opt = arg->getOption();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
884 warnIfDeprecatedOption(opt);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
885 warnIfUnimplementedOption(opt);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
886
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
887 switch (opt.getID()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
888 case OPT_INPUT:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
889 addFile(rerootPath(arg->getValue()), /*forceLoadArchive=*/false);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
890 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
891 case OPT_needed_library:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
892 if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
893 addFile(rerootPath(arg->getValue()), false)))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
894 dylibFile->forceNeeded = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
895 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
896 case OPT_reexport_library:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
897 if (auto *dylibFile = dyn_cast_or_null<DylibFile>(addFile(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
898 rerootPath(arg->getValue()), /*forceLoadArchive=*/false))) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
899 config->hasReexports = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
900 dylibFile->reexport = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
901 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
902 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
903 case OPT_weak_library:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
904 if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
905 addFile(rerootPath(arg->getValue()), /*forceLoadArchive=*/false)))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
906 dylibFile->forceWeakImport = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
907 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
908 case OPT_filelist:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
909 addFileList(arg->getValue());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
910 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
911 case OPT_force_load:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
912 addFile(rerootPath(arg->getValue()), /*forceLoadArchive=*/true);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
913 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
914 case OPT_l:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
915 case OPT_needed_l:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
916 case OPT_reexport_l:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
917 case OPT_weak_l:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
918 addLibrary(arg->getValue(), opt.getID() == OPT_needed_l,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
919 opt.getID() == OPT_weak_l, opt.getID() == OPT_reexport_l,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
920 /*isExplicit=*/true);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
921 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
922 case OPT_framework:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
923 case OPT_needed_framework:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
924 case OPT_reexport_framework:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
925 case OPT_weak_framework:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
926 addFramework(arg->getValue(), opt.getID() == OPT_needed_framework,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
927 opt.getID() == OPT_weak_framework,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
928 opt.getID() == OPT_reexport_framework, /*isExplicit=*/true);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
929 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
930 default:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
931 break;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
932 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
933 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
934 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
935
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
936 bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
937 raw_ostream &stdoutOS, raw_ostream &stderrOS) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
938 lld::stdoutOS = &stdoutOS;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
939 lld::stderrOS = &stderrOS;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
940
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
941 errorHandler().cleanupCallback = []() { freeArena(); };
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
942
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
943 errorHandler().logName = args::getFilenameWithoutExe(argsArr[0]);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
944 stderrOS.enable_colors(stderrOS.has_colors());
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
945
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
946 MachOOptTable parser;
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
947 InputArgList args = parser.parse(argsArr.slice(1));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
948
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
949 errorHandler().errorLimitExceededMsg =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
950 "too many errors emitted, stopping now "
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
951 "(use --error-limit=0 to see all errors)";
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
952 errorHandler().errorLimit = args::getInteger(args, OPT_error_limit_eq, 20);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
953 errorHandler().verbose = args.hasArg(OPT_verbose);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
954
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
955 if (args.hasArg(OPT_help_hidden)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
956 parser.printHelp(argsArr[0], /*showHidden=*/true);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
957 return true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
958 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
959 if (args.hasArg(OPT_help)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
960 parser.printHelp(argsArr[0], /*showHidden=*/false);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
961 return true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
962 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
963 if (args.hasArg(OPT_version)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
964 message(getLLDVersion());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
965 return true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
966 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
967
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 config = make<Configuration>();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
969 symtab = make<SymbolTable>();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
970 target = createTargetInfo(args);
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
971 depTracker =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
972 make<DependencyTracker>(args.getLastArgValue(OPT_dependency_info));
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
973
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
974 // Must be set before any InputSections and Symbols are created.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
975 config->deadStrip = args.hasArg(OPT_dead_strip);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
976
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
977 config->systemLibraryRoots = getSystemLibraryRoots(args);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
978 if (const char *path = getReproduceOption(args)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
979 // Note that --reproduce is a debug option so you can ignore it
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
980 // if you are trying to understand the whole picture of the code.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
981 Expected<std::unique_ptr<TarWriter>> errOrWriter =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
982 TarWriter::create(path, path::stem(path));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
983 if (errOrWriter) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
984 tar = std::move(*errOrWriter);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
985 tar->append("response.txt", createResponseFile(args));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
986 tar->append("version.txt", getLLDVersion() + "\n");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
987 } else {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
988 error("--reproduce: " + toString(errOrWriter.takeError()));
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
989 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
990 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
991
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
992 if (auto *arg = args.getLastArg(OPT_threads_eq)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
993 StringRef v(arg->getValue());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
994 unsigned threads = 0;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
995 if (!llvm::to_integer(v, threads, 0) || threads == 0)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
996 error(arg->getSpelling() + ": expected a positive integer, but got '" +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
997 arg->getValue() + "'");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
998 parallel::strategy = hardware_concurrency(threads);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
999 config->thinLTOJobs = v;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1000 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1001 if (auto *arg = args.getLastArg(OPT_thinlto_jobs_eq))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1002 config->thinLTOJobs = arg->getValue();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1003 if (!get_threadpool_strategy(config->thinLTOJobs))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1004 error("--thinlto-jobs: invalid job count: " + config->thinLTOJobs);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1005
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1006 for (const Arg *arg : args.filtered(OPT_u)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1007 config->explicitUndefineds.push_back(symtab->addUndefined(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1008 arg->getValue(), /*file=*/nullptr, /*isWeakRef=*/false));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1009 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1010
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1011 for (const Arg *arg : args.filtered(OPT_U))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1012 symtab->addDynamicLookup(arg->getValue());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1013
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1014 config->mapFile = args.getLastArgValue(OPT_map);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1015 config->outputFile = args.getLastArgValue(OPT_o, "a.out");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1016 config->astPaths = args.getAllArgValues(OPT_add_ast_path);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1017 config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1018 config->headerPadMaxInstallNames =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1019 args.hasArg(OPT_headerpad_max_install_names);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1020 config->printEachFile = args.hasArg(OPT_t);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1021 config->printWhyLoad = args.hasArg(OPT_why_load);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1022 config->outputType = getOutputType(args);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1023 if (const Arg *arg = args.getLastArg(OPT_bundle_loader)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1024 if (config->outputType != MH_BUNDLE)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1025 error("-bundle_loader can only be used with MachO bundle output");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1026 addFile(arg->getValue(), /*forceLoadArchive=*/false, /*isExplicit=*/false,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1027 /*isBundleLoader=*/true);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1028 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1029 config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1030 config->ltoNewPassManager =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1031 args.hasFlag(OPT_no_lto_legacy_pass_manager, OPT_lto_legacy_pass_manager,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1032 LLVM_ENABLE_NEW_PASS_MANAGER);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1033 config->runtimePaths = args::getStrings(args, OPT_rpath);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1034 config->allLoad = args.hasArg(OPT_all_load);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1035 config->forceLoadObjC = args.hasArg(OPT_ObjC);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1036 config->deadStripDylibs = args.hasArg(OPT_dead_strip_dylibs);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1037 config->demangle = args.hasArg(OPT_demangle);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1038 config->implicitDylibs = !args.hasArg(OPT_no_implicit_dylibs);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1039 config->emitFunctionStarts = !args.hasArg(OPT_no_function_starts);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1040 config->emitBitcodeBundle = args.hasArg(OPT_bitcode_bundle);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1041
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1042 // FIXME: Add a commandline flag for this too.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1043 config->zeroModTime = getenv("ZERO_AR_DATE");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1044
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1045 std::array<PlatformKind, 3> encryptablePlatforms{
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1046 PlatformKind::iOS, PlatformKind::watchOS, PlatformKind::tvOS};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1047 config->emitEncryptionInfo =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1048 args.hasFlag(OPT_encryptable, OPT_no_encryption,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1049 is_contained(encryptablePlatforms, config->platform()));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1050
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1051 #ifndef LLVM_HAVE_LIBXAR
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1052 if (config->emitBitcodeBundle)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1053 error("-bitcode_bundle unsupported because LLD wasn't built with libxar");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1054 #endif
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1055
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1056 if (const Arg *arg = args.getLastArg(OPT_install_name)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1057 if (config->outputType != MH_DYLIB)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1058 warn(arg->getAsString(args) + ": ignored, only has effect with -dylib");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1059 else
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1060 config->installName = arg->getValue();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1061 } else if (config->outputType == MH_DYLIB) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1062 config->installName = config->outputFile;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1063 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1064
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1065 if (args.hasArg(OPT_mark_dead_strippable_dylib)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1066 if (config->outputType != MH_DYLIB)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1067 warn("-mark_dead_strippable_dylib: ignored, only has effect with -dylib");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1068 else
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1069 config->markDeadStrippableDylib = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1070 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1071
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1072 if (const Arg *arg = args.getLastArg(OPT_static, OPT_dynamic))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1073 config->staticLink = (arg->getOption().getID() == OPT_static);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1074
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1075 if (const Arg *arg =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1076 args.getLastArg(OPT_flat_namespace, OPT_twolevel_namespace))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1077 config->namespaceKind = arg->getOption().getID() == OPT_twolevel_namespace
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1078 ? NamespaceKind::twolevel
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1079 : NamespaceKind::flat;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1080
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1081 config->undefinedSymbolTreatment = getUndefinedSymbolTreatment(args);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1082
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1083 if (config->outputType == MH_EXECUTE)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1084 config->entry = symtab->addUndefined(args.getLastArgValue(OPT_e, "_main"),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1085 /*file=*/nullptr,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1086 /*isWeakRef=*/false);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1087
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1088 config->librarySearchPaths =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1089 getLibrarySearchPaths(args, config->systemLibraryRoots);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1090 config->frameworkSearchPaths =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1091 getFrameworkSearchPaths(args, config->systemLibraryRoots);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1092 if (const Arg *arg =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1093 args.getLastArg(OPT_search_paths_first, OPT_search_dylibs_first))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1094 config->searchDylibsFirst =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1095 arg->getOption().getID() == OPT_search_dylibs_first;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1096
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1097 config->dylibCompatibilityVersion =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1098 parseDylibVersion(args, OPT_compatibility_version);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1099 config->dylibCurrentVersion = parseDylibVersion(args, OPT_current_version);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1100
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1101 config->dataConst =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1102 args.hasFlag(OPT_data_const, OPT_no_data_const, dataConstDefault(args));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1103 // Populate config->sectionRenameMap with builtin default renames.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1104 // Options -rename_section and -rename_segment are able to override.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1105 initializeSectionRenameMap();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1106 // Reject every special character except '.' and '$'
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1107 // TODO(gkm): verify that this is the proper set of invalid chars
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1108 StringRef invalidNameChars("!\"#%&'()*+,-/:;<=>?@[\\]^`{|}~");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1109 auto validName = [invalidNameChars](StringRef s) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1110 if (s.find_first_of(invalidNameChars) != StringRef::npos)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1111 error("invalid name for segment or section: " + s);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1112 return s;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1113 };
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1114 for (const Arg *arg : args.filtered(OPT_rename_section)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1115 config->sectionRenameMap[{validName(arg->getValue(0)),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1116 validName(arg->getValue(1))}] = {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1117 validName(arg->getValue(2)), validName(arg->getValue(3))};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1118 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1119 for (const Arg *arg : args.filtered(OPT_rename_segment)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1120 config->segmentRenameMap[validName(arg->getValue(0))] =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1121 validName(arg->getValue(1));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1122 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1123
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1124 config->sectionAlignments = parseSectAlign(args);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1125
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1126 for (const Arg *arg : args.filtered(OPT_segprot)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1127 StringRef segName = arg->getValue(0);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1128 uint32_t maxProt = parseProtection(arg->getValue(1));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1129 uint32_t initProt = parseProtection(arg->getValue(2));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1130 if (maxProt != initProt && config->arch() != AK_i386)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1131 error("invalid argument '" + arg->getAsString(args) +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1132 "': max and init must be the same for non-i386 archs");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1133 if (segName == segment_names::linkEdit)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1134 error("-segprot cannot be used to change __LINKEDIT's protections");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1135 config->segmentProtections.push_back({segName, maxProt, initProt});
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1136 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1137
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1138 handleSymbolPatterns(args, config->exportedSymbols, OPT_exported_symbol,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1139 OPT_exported_symbols_list);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1140 handleSymbolPatterns(args, config->unexportedSymbols, OPT_unexported_symbol,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1141 OPT_unexported_symbols_list);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1142 if (!config->exportedSymbols.empty() && !config->unexportedSymbols.empty()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1143 error("cannot use both -exported_symbol* and -unexported_symbol* options\n"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1144 ">>> ignoring unexports");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1145 config->unexportedSymbols.clear();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1146 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1147 // Explicitly-exported literal symbols must be defined, but might
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1148 // languish in an archive if unreferenced elsewhere. Light a fire
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1149 // under those lazy symbols!
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1150 for (const CachedHashStringRef &cachedName : config->exportedSymbols.literals)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1151 symtab->addUndefined(cachedName.val(), /*file=*/nullptr,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1152 /*isWeakRef=*/false);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1154 config->saveTemps = args.hasArg(OPT_save_temps);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1155
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1156 config->adhocCodesign = args.hasFlag(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1157 OPT_adhoc_codesign, OPT_no_adhoc_codesign,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1158 (config->arch() == AK_arm64 || config->arch() == AK_arm64e) &&
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1159 config->platform() == PlatformKind::macOS);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1160
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1161 if (args.hasArg(OPT_v)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1162 message(getLLDVersion());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1163 message(StringRef("Library search paths:") +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1164 (config->librarySearchPaths.empty()
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1165 ? ""
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1166 : "\n\t" + join(config->librarySearchPaths, "\n\t")));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1167 message(StringRef("Framework search paths:") +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1168 (config->frameworkSearchPaths.empty()
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1169 ? ""
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1170 : "\n\t" + join(config->frameworkSearchPaths, "\n\t")));
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1171 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1172
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1173 config->progName = argsArr[0];
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1174
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1175 config->timeTraceEnabled = args.hasArg(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1176 OPT_time_trace, OPT_time_trace_granularity_eq, OPT_time_trace_file_eq);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1177 config->timeTraceGranularity =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1178 args::getInteger(args, OPT_time_trace_granularity_eq, 500);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1179
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1180 // Initialize time trace profiler.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1181 if (config->timeTraceEnabled)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1182 timeTraceProfilerInitialize(config->timeTraceGranularity, config->progName);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1183
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1184 {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1185 TimeTraceScope timeScope("ExecuteLinker");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1186
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1187 initLLVM(); // must be run before any call to addFile()
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1188 createFiles(args);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1189
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1190 config->isPic = config->outputType == MH_DYLIB ||
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1191 config->outputType == MH_BUNDLE ||
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1192 (config->outputType == MH_EXECUTE &&
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1193 args.hasFlag(OPT_pie, OPT_no_pie, true));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1194
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1195 // Now that all dylibs have been loaded, search for those that should be
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1196 // re-exported.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1197 {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1198 auto reexportHandler = [](const Arg *arg,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1199 const std::vector<StringRef> &extensions) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1200 config->hasReexports = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1201 StringRef searchName = arg->getValue();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1202 if (!markReexport(searchName, extensions))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1203 error(arg->getSpelling() + " " + searchName +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1204 " does not match a supplied dylib");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1205 };
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1206 std::vector<StringRef> extensions = {".tbd"};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1207 for (const Arg *arg : args.filtered(OPT_sub_umbrella))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1208 reexportHandler(arg, extensions);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1209
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1210 extensions.push_back(".dylib");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1211 for (const Arg *arg : args.filtered(OPT_sub_library))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1212 reexportHandler(arg, extensions);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1213 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1214
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1215 // Parse LTO options.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1216 if (const Arg *arg = args.getLastArg(OPT_mcpu))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1217 parseClangOption(saver.save("-mcpu=" + StringRef(arg->getValue())),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1218 arg->getSpelling());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1219
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1220 for (const Arg *arg : args.filtered(OPT_mllvm))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1221 parseClangOption(arg->getValue(), arg->getSpelling());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1222
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1223 compileBitcodeFiles();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1224 replaceCommonSymbols();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1225
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1226 StringRef orderFile = args.getLastArgValue(OPT_order_file);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1227 if (!orderFile.empty())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1228 parseOrderFile(orderFile);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1229
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1230 if (config->entry)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1231 if (auto *undefined = dyn_cast<Undefined>(config->entry))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1232 treatUndefinedSymbol(*undefined, "the entry point");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1233
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1234 // FIXME: This prints symbols that are undefined both in input files and
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1235 // via -u flag twice.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1236 for (const Symbol *sym : config->explicitUndefineds) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1237 if (const auto *undefined = dyn_cast<Undefined>(sym))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1238 treatUndefinedSymbol(*undefined, "-u");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1239 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1240 // Literal exported-symbol names must be defined, but glob
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1241 // patterns need not match.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1242 for (const CachedHashStringRef &cachedName :
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1243 config->exportedSymbols.literals) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1244 if (const Symbol *sym = symtab->find(cachedName))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1245 if (const auto *undefined = dyn_cast<Undefined>(sym))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1246 treatUndefinedSymbol(*undefined, "-exported_symbol(s_list)");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1247 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1248
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1249 // FIXME: should terminate the link early based on errors encountered so
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1250 // far?
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1251
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1252 createSyntheticSections();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1253 createSyntheticSymbols();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1254
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1255 if (!config->exportedSymbols.empty()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1256 for (Symbol *sym : symtab->getSymbols()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1257 if (auto *defined = dyn_cast<Defined>(sym)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1258 StringRef symbolName = defined->getName();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1259 if (config->exportedSymbols.match(symbolName)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1260 if (defined->privateExtern) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1261 error("cannot export hidden symbol " + symbolName +
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1262 "\n>>> defined in " + toString(defined->getFile()));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1263 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1264 } else {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1265 defined->privateExtern = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1266 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1267 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1268 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1269 } else if (!config->unexportedSymbols.empty()) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1270 for (Symbol *sym : symtab->getSymbols())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1271 if (auto *defined = dyn_cast<Defined>(sym))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1272 if (config->unexportedSymbols.match(defined->getName()))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1273 defined->privateExtern = true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1274 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1275
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1276 for (const Arg *arg : args.filtered(OPT_sectcreate)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1277 StringRef segName = arg->getValue(0);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1278 StringRef sectName = arg->getValue(1);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1279 StringRef fileName = arg->getValue(2);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1280 Optional<MemoryBufferRef> buffer = readFile(fileName);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1281 if (buffer)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1282 inputFiles.insert(make<OpaqueFile>(*buffer, segName, sectName));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1283 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1284
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1285 {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1286 TimeTraceScope timeScope("Gathering input sections");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1287 // Gather all InputSections into one vector.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1288 for (const InputFile *file : inputFiles) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1289 for (const SubsectionMap &map : file->subsections)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1290 for (const SubsectionEntry &subsectionEntry : map)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1291 inputSections.push_back(subsectionEntry.isec);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1292 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1293 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1294
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1295 if (config->deadStrip)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1296 markLive();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1297
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1298 // Write to an output file.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1299 if (target->wordSize == 8)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1300 writeResult<LP64>();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1301 else
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1302 writeResult<ILP32>();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1303
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1304 depTracker->write(getLLDVersion(), inputFiles, config->outputFile);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1306
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1307 if (config->timeTraceEnabled) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1308 if (auto E = timeTraceProfilerWrite(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1309 args.getLastArgValue(OPT_time_trace_file_eq).str(),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1310 config->outputFile)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1311 handleAllErrors(std::move(E),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1312 [&](const StringError &SE) { error(SE.getMessage()); });
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1313 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
1315 timeTraceProfilerCleanup();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1316 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1317
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1318 if (canExitEarly)
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1319 exitLld(errorCount() ? 1 : 0);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1320
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1321 return !errorCount();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1322 }