Bug Summary

File:tools/lld/lib/Driver/DarwinLdDriver.cpp
Warning:line 533, column 24
The result of the left shift is undefined due to shifting by '64', which is greater or equal to the width of type 'int'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DarwinLdDriver.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lld/lib/Driver -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lld/lib/Driver -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lld/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lld/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lld/lib/Driver -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-04-11-031539-24776-1 -x c++ /build/llvm-toolchain-snapshot-7~svn329677/tools/lld/lib/Driver/DarwinLdDriver.cpp
1//===- lib/Driver/DarwinLdDriver.cpp --------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11///
12/// Concrete instance of the Driver for darwin's ld.
13///
14//===----------------------------------------------------------------------===//
15
16#include "lld/Common/LLVM.h"
17#include "lld/Core/ArchiveLibraryFile.h"
18#include "lld/Core/Error.h"
19#include "lld/Core/File.h"
20#include "lld/Core/Instrumentation.h"
21#include "lld/Core/LinkingContext.h"
22#include "lld/Core/Node.h"
23#include "lld/Core/PassManager.h"
24#include "lld/Core/Resolver.h"
25#include "lld/Core/SharedLibraryFile.h"
26#include "lld/Core/Simple.h"
27#include "lld/ReaderWriter/MachOLinkingContext.h"
28#include "llvm/ADT/ArrayRef.h"
29#include "llvm/ADT/Optional.h"
30#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/SmallString.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/ADT/Twine.h"
35#include "llvm/BinaryFormat/MachO.h"
36#include "llvm/Option/Arg.h"
37#include "llvm/Option/ArgList.h"
38#include "llvm/Option/OptTable.h"
39#include "llvm/Option/Option.h"
40#include "llvm/Support/Casting.h"
41#include "llvm/Support/CommandLine.h"
42#include "llvm/Support/Error.h"
43#include "llvm/Support/ErrorOr.h"
44#include "llvm/Support/Format.h"
45#include "llvm/Support/MathExtras.h"
46#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/Path.h"
48#include "llvm/Support/raw_ostream.h"
49#include <algorithm>
50#include <cstdint>
51#include <memory>
52#include <string>
53#include <system_error>
54#include <utility>
55#include <vector>
56
57using namespace lld;
58
59namespace {
60
61// Create enum with OPT_xxx values for each option in DarwinLdOptions.td
62enum {
63 OPT_INVALID = 0,
64#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
65 HELP, META, VALUES) \
66 OPT_##ID,
67#include "DarwinLdOptions.inc"
68#undef OPTION
69};
70
71// Create prefix string literals used in DarwinLdOptions.td
72#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
73#include "DarwinLdOptions.inc"
74#undef PREFIX
75
76// Create table mapping all options defined in DarwinLdOptions.td
77static const llvm::opt::OptTable::Info InfoTable[] = {
78#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
79 HELPTEXT, METAVAR, VALUES) \
80 {PREFIX, NAME, HELPTEXT, \
81 METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
82 PARAM, FLAGS, OPT_##GROUP, \
83 OPT_##ALIAS, ALIASARGS, VALUES},
84#include "DarwinLdOptions.inc"
85#undef OPTION
86};
87
88// Create OptTable class for parsing actual command line arguments
89class DarwinLdOptTable : public llvm::opt::OptTable {
90public:
91 DarwinLdOptTable() : OptTable(InfoTable) {}
92};
93
94static std::vector<std::unique_ptr<File>>
95makeErrorFile(StringRef path, std::error_code ec) {
96 std::vector<std::unique_ptr<File>> result;
97 result.push_back(llvm::make_unique<ErrorFile>(path, ec));
98 return result;
99}
100
101static std::vector<std::unique_ptr<File>>
102parseMemberFiles(std::unique_ptr<File> file) {
103 std::vector<std::unique_ptr<File>> members;
104 if (auto *archive = dyn_cast<ArchiveLibraryFile>(file.get())) {
105 if (std::error_code ec = archive->parseAllMembers(members))
106 return makeErrorFile(file->path(), ec);
107 } else {
108 members.push_back(std::move(file));
109 }
110 return members;
111}
112
113std::vector<std::unique_ptr<File>>
114loadFile(MachOLinkingContext &ctx, StringRef path,
115 raw_ostream &diag, bool wholeArchive, bool upwardDylib) {
116 if (ctx.logInputFiles())
117 diag << path << "\n";
118
119 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = ctx.getMemoryBuffer(path);
120 if (std::error_code ec = mbOrErr.getError())
121 return makeErrorFile(path, ec);
122 ErrorOr<std::unique_ptr<File>> fileOrErr =
123 ctx.registry().loadFile(std::move(mbOrErr.get()));
124 if (std::error_code ec = fileOrErr.getError())
125 return makeErrorFile(path, ec);
126 std::unique_ptr<File> &file = fileOrErr.get();
127
128 // If file is a dylib, inform LinkingContext about it.
129 if (SharedLibraryFile *shl = dyn_cast<SharedLibraryFile>(file.get())) {
130 if (std::error_code ec = shl->parse())
131 return makeErrorFile(path, ec);
132 ctx.registerDylib(reinterpret_cast<mach_o::MachODylibFile *>(shl),
133 upwardDylib);
134 }
135 if (wholeArchive)
136 return parseMemberFiles(std::move(file));
137 std::vector<std::unique_ptr<File>> files;
138 files.push_back(std::move(file));
139 return files;
140}
141
142} // end anonymous namespace
143
144// Test may be running on Windows. Canonicalize the path
145// separator to '/' to get consistent outputs for tests.
146static std::string canonicalizePath(StringRef path) {
147 char sep = llvm::sys::path::get_separator().front();
148 if (sep != '/') {
149 std::string fixedPath = path;
150 std::replace(fixedPath.begin(), fixedPath.end(), sep, '/');
151 return fixedPath;
152 } else {
153 return path;
154 }
155}
156
157static void addFile(StringRef path, MachOLinkingContext &ctx,
158 bool loadWholeArchive,
159 bool upwardDylib, raw_ostream &diag) {
160 std::vector<std::unique_ptr<File>> files =
161 loadFile(ctx, path, diag, loadWholeArchive, upwardDylib);
162 for (std::unique_ptr<File> &file : files)
163 ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
164}
165
166// Export lists are one symbol per line. Blank lines are ignored.
167// Trailing comments start with #.
168static std::error_code parseExportsList(StringRef exportFilePath,
169 MachOLinkingContext &ctx,
170 raw_ostream &diagnostics) {
171 // Map in export list file.
172 ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
173 MemoryBuffer::getFileOrSTDIN(exportFilePath);
174 if (std::error_code ec = mb.getError())
175 return ec;
176 ctx.addInputFileDependency(exportFilePath);
177 StringRef buffer = mb->get()->getBuffer();
178 while (!buffer.empty()) {
179 // Split off each line in the file.
180 std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
181 StringRef line = lineAndRest.first;
182 // Ignore trailing # comments.
183 std::pair<StringRef, StringRef> symAndComment = line.split('#');
184 StringRef sym = symAndComment.first.trim();
185 if (!sym.empty())
186 ctx.addExportSymbol(sym);
187 buffer = lineAndRest.second;
188 }
189 return std::error_code();
190}
191
192/// Order files are one symbol per line. Blank lines are ignored.
193/// Trailing comments start with #. Symbol names can be prefixed with an
194/// architecture name and/or .o leaf name. Examples:
195/// _foo
196/// bar.o:_bar
197/// libfrob.a(bar.o):_bar
198/// x86_64:_foo64
199static std::error_code parseOrderFile(StringRef orderFilePath,
200 MachOLinkingContext &ctx,
201 raw_ostream &diagnostics) {
202 // Map in order file.
203 ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
204 MemoryBuffer::getFileOrSTDIN(orderFilePath);
205 if (std::error_code ec = mb.getError())
206 return ec;
207 ctx.addInputFileDependency(orderFilePath);
208 StringRef buffer = mb->get()->getBuffer();
209 while (!buffer.empty()) {
210 // Split off each line in the file.
211 std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
212 StringRef line = lineAndRest.first;
213 buffer = lineAndRest.second;
214 // Ignore trailing # comments.
215 std::pair<StringRef, StringRef> symAndComment = line.split('#');
216 if (symAndComment.first.empty())
217 continue;
218 StringRef sym = symAndComment.first.trim();
219 if (sym.empty())
220 continue;
221 // Check for prefix.
222 StringRef prefix;
223 std::pair<StringRef, StringRef> prefixAndSym = sym.split(':');
224 if (!prefixAndSym.second.empty()) {
225 sym = prefixAndSym.second;
226 prefix = prefixAndSym.first;
227 if (!prefix.endswith(".o") && !prefix.endswith(".o)")) {
228 // If arch name prefix does not match arch being linked, ignore symbol.
229 if (!ctx.archName().equals(prefix))
230 continue;
231 prefix = "";
232 }
233 } else
234 sym = prefixAndSym.first;
235 if (!sym.empty()) {
236 ctx.appendOrderedSymbol(sym, prefix);
237 //llvm::errs() << sym << ", prefix=" << prefix << "\n";
238 }
239 }
240 return std::error_code();
241}
242
243//
244// There are two variants of the -filelist option:
245//
246// -filelist <path>
247// In this variant, the path is to a text file which contains one file path
248// per line. There are no comments or trimming of whitespace.
249//
250// -fileList <path>,<dir>
251// In this variant, the path is to a text file which contains a partial path
252// per line. The <dir> prefix is prepended to each partial path.
253//
254static llvm::Error loadFileList(StringRef fileListPath,
255 MachOLinkingContext &ctx, bool forceLoad,
256 raw_ostream &diagnostics) {
257 // If there is a comma, split off <dir>.
258 std::pair<StringRef, StringRef> opt = fileListPath.split(',');
259 StringRef filePath = opt.first;
260 StringRef dirName = opt.second;
261 ctx.addInputFileDependency(filePath);
262 // Map in file list file.
263 ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
264 MemoryBuffer::getFileOrSTDIN(filePath);
265 if (std::error_code ec = mb.getError())
266 return llvm::errorCodeToError(ec);
267 StringRef buffer = mb->get()->getBuffer();
268 while (!buffer.empty()) {
269 // Split off each line in the file.
270 std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
271 StringRef line = lineAndRest.first;
272 StringRef path;
273 if (!dirName.empty()) {
274 // If there is a <dir> then prepend dir to each line.
275 SmallString<256> fullPath;
276 fullPath.assign(dirName);
277 llvm::sys::path::append(fullPath, Twine(line));
278 path = ctx.copy(fullPath.str());
279 } else {
280 // No <dir> use whole line as input file path.
281 path = ctx.copy(line);
282 }
283 if (!ctx.pathExists(path)) {
284 return llvm::make_error<GenericError>(Twine("File not found '")
285 + path
286 + "'");
287 }
288 if (ctx.testingFileUsage()) {
289 diagnostics << "Found filelist entry " << canonicalizePath(path) << '\n';
290 }
291 addFile(path, ctx, forceLoad, false, diagnostics);
292 buffer = lineAndRest.second;
293 }
294 return llvm::Error::success();
295}
296
297/// Parse number assuming it is base 16, but allow 0x prefix.
298static bool parseNumberBase16(StringRef numStr, uint64_t &baseAddress) {
299 if (numStr.startswith_lower("0x"))
300 numStr = numStr.drop_front(2);
301 return numStr.getAsInteger(16, baseAddress);
302}
303
304static void parseLLVMOptions(const LinkingContext &ctx) {
305 // Honor -mllvm
306 if (!ctx.llvmOptions().empty()) {
307 unsigned numArgs = ctx.llvmOptions().size();
308 auto **args = new const char *[numArgs + 2];
309 args[0] = "lld (LLVM option parsing)";
310 for (unsigned i = 0; i != numArgs; ++i)
311 args[i + 1] = ctx.llvmOptions()[i];
312 args[numArgs + 1] = nullptr;
313 llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
314 }
315}
316
317namespace lld {
318namespace mach_o {
319
320bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx,
321 raw_ostream &diagnostics) {
322 // Parse command line options using DarwinLdOptions.td
323 DarwinLdOptTable table;
324 unsigned missingIndex;
325 unsigned missingCount;
326 llvm::opt::InputArgList parsedArgs =
327 table.ParseArgs(args.slice(1), missingIndex, missingCount);
328 if (missingCount) {
1
Assuming 'missingCount' is 0
2
Taking false branch
329 diagnostics << "error: missing arg value for '"
330 << parsedArgs.getArgString(missingIndex) << "' expected "
331 << missingCount << " argument(s).\n";
332 return false;
333 }
334
335 for (auto unknownArg : parsedArgs.filtered(OPT_UNKNOWN)) {
336 diagnostics << "warning: ignoring unknown argument: "
337 << unknownArg->getAsString(parsedArgs) << "\n";
338 }
339
340 // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static )
341 llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE;
342 bool isStaticExecutable = false;
343 if (llvm::opt::Arg *kind = parsedArgs.getLastArg(
3
Assuming 'kind' is null
4
Taking false branch
344 OPT_dylib, OPT_relocatable, OPT_bundle, OPT_static, OPT_preload)) {
345 switch (kind->getOption().getID()) {
346 case OPT_dylib:
347 fileType = llvm::MachO::MH_DYLIB;
348 break;
349 case OPT_relocatable:
350 fileType = llvm::MachO::MH_OBJECT;
351 break;
352 case OPT_bundle:
353 fileType = llvm::MachO::MH_BUNDLE;
354 break;
355 case OPT_static:
356 fileType = llvm::MachO::MH_EXECUTE;
357 isStaticExecutable = true;
358 break;
359 case OPT_preload:
360 fileType = llvm::MachO::MH_PRELOAD;
361 break;
362 }
363 }
364
365 // Handle -arch xxx
366 MachOLinkingContext::Arch arch = MachOLinkingContext::arch_unknown;
367 if (llvm::opt::Arg *archStr = parsedArgs.getLastArg(OPT_arch)) {
5
Assuming 'archStr' is null
6
Taking false branch
368 arch = MachOLinkingContext::archFromName(archStr->getValue());
369 if (arch == MachOLinkingContext::arch_unknown) {
370 diagnostics << "error: unknown arch named '" << archStr->getValue()
371 << "'\n";
372 return false;
373 }
374 }
375 // If no -arch specified, scan input files to find first non-fat .o file.
376 if (arch == MachOLinkingContext::arch_unknown) {
7
Taking true branch
377 for (auto &inFile : parsedArgs.filtered(OPT_INPUT)) {
378 // This is expensive because it opens and maps the file. But that is
379 // ok because no -arch is rare.
380 if (MachOLinkingContext::isThinObjectFile(inFile->getValue(), arch))
8
Assuming the condition is true
9
Taking true branch
381 break;
10
Execution continues on line 383
382 }
383 if (arch == MachOLinkingContext::arch_unknown &&
11
Assuming 'arch' is not equal to arch_unknown
384 !parsedArgs.getLastArg(OPT_test_file_usage)) {
385 // If no -arch and no options at all, print usage message.
386 if (parsedArgs.size() == 0)
387 table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);
388 else
389 diagnostics << "error: -arch not specified and could not be inferred\n";
390 return false;
391 }
392 }
393
394 // Handle -macosx_version_min or -ios_version_min
395 MachOLinkingContext::OS os = MachOLinkingContext::OS::unknown;
396 uint32_t minOSVersion = 0;
397 if (llvm::opt::Arg *minOS =
12
Assuming 'minOS' is null
13
Taking false branch
398 parsedArgs.getLastArg(OPT_macosx_version_min, OPT_ios_version_min,
399 OPT_ios_simulator_version_min)) {
400 switch (minOS->getOption().getID()) {
401 case OPT_macosx_version_min:
402 os = MachOLinkingContext::OS::macOSX;
403 if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
404 minOSVersion)) {
405 diagnostics << "error: malformed macosx_version_min value\n";
406 return false;
407 }
408 break;
409 case OPT_ios_version_min:
410 os = MachOLinkingContext::OS::iOS;
411 if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
412 minOSVersion)) {
413 diagnostics << "error: malformed ios_version_min value\n";
414 return false;
415 }
416 break;
417 case OPT_ios_simulator_version_min:
418 os = MachOLinkingContext::OS::iOS_simulator;
419 if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
420 minOSVersion)) {
421 diagnostics << "error: malformed ios_simulator_version_min value\n";
422 return false;
423 }
424 break;
425 }
426 } else {
427 // No min-os version on command line, check environment variables
428 }
429
430 // Handle export_dynamic
431 // FIXME: Should we warn when this applies to something other than a static
432 // executable or dylib? Those are the only cases where this has an effect.
433 // Note, this has to come before ctx.configure() so that we get the correct
434 // value for _globalsAreDeadStripRoots.
435 bool exportDynamicSymbols = parsedArgs.hasArg(OPT_export_dynamic);
436
437 // Now that there's enough information parsed in, let the linking context
438 // set up default values.
439 ctx.configure(fileType, arch, os, minOSVersion, exportDynamicSymbols);
440
441 // Handle -e xxx
442 if (llvm::opt::Arg *entry = parsedArgs.getLastArg(OPT_entry))
14
Assuming 'entry' is null
15
Taking false branch
443 ctx.setEntrySymbolName(entry->getValue());
444
445 // Handle -o xxx
446 if (llvm::opt::Arg *outpath = parsedArgs.getLastArg(OPT_output))
16
Assuming 'outpath' is null
17
Taking false branch
447 ctx.setOutputPath(outpath->getValue());
448 else
449 ctx.setOutputPath("a.out");
450
451 // Handle -image_base XXX and -seg1addr XXXX
452 if (llvm::opt::Arg *imageBase = parsedArgs.getLastArg(OPT_image_base)) {
18
Assuming 'imageBase' is null
19
Taking false branch
453 uint64_t baseAddress;
454 if (parseNumberBase16(imageBase->getValue(), baseAddress)) {
455 diagnostics << "error: image_base expects a hex number\n";
456 return false;
457 } else if (baseAddress < ctx.pageZeroSize()) {
458 diagnostics << "error: image_base overlaps with __PAGEZERO\n";
459 return false;
460 } else if (baseAddress % ctx.pageSize()) {
461 diagnostics << "error: image_base must be a multiple of page size ("
462 << "0x" << llvm::utohexstr(ctx.pageSize()) << ")\n";
463 return false;
464 }
465
466 ctx.setBaseAddress(baseAddress);
467 }
468
469 // Handle -dead_strip
470 if (parsedArgs.getLastArg(OPT_dead_strip))
20
Assuming the condition is false
21
Taking false branch
471 ctx.setDeadStripping(true);
472
473 bool globalWholeArchive = false;
474 // Handle -all_load
475 if (parsedArgs.getLastArg(OPT_all_load))
22
Assuming the condition is false
23
Taking false branch
476 globalWholeArchive = true;
477
478 // Handle -install_name
479 if (llvm::opt::Arg *installName = parsedArgs.getLastArg(OPT_install_name))
24
Assuming 'installName' is null
25
Taking false branch
480 ctx.setInstallName(installName->getValue());
481 else
482 ctx.setInstallName(ctx.outputPath());
483
484 // Handle -mark_dead_strippable_dylib
485 if (parsedArgs.getLastArg(OPT_mark_dead_strippable_dylib))
26
Assuming the condition is false
27
Taking false branch
486 ctx.setDeadStrippableDylib(true);
487
488 // Handle -compatibility_version and -current_version
489 if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_compatibility_version)) {
28
Assuming 'vers' is null
29
Taking false branch
490 if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) {
491 diagnostics
492 << "error: -compatibility_version can only be used with -dylib\n";
493 return false;
494 }
495 uint32_t parsedVers;
496 if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) {
497 diagnostics << "error: -compatibility_version value is malformed\n";
498 return false;
499 }
500 ctx.setCompatibilityVersion(parsedVers);
501 }
502
503 if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_current_version)) {
30
Assuming 'vers' is null
31
Taking false branch
504 if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) {
505 diagnostics << "-current_version can only be used with -dylib\n";
506 return false;
507 }
508 uint32_t parsedVers;
509 if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) {
510 diagnostics << "error: -current_version value is malformed\n";
511 return false;
512 }
513 ctx.setCurrentVersion(parsedVers);
514 }
515
516 // Handle -bundle_loader
517 if (llvm::opt::Arg *loader = parsedArgs.getLastArg(OPT_bundle_loader))
32
Assuming 'loader' is null
33
Taking false branch
518 ctx.setBundleLoader(loader->getValue());
519
520 // Handle -sectalign segname sectname align
521 for (auto &alignArg : parsedArgs.filtered(OPT_sectalign)) {
522 const char* segName = alignArg->getValue(0);
523 const char* sectName = alignArg->getValue(1);
524 const char* alignStr = alignArg->getValue(2);
525 if ((alignStr[0] == '0') && (alignStr[1] == 'x'))
34
Assuming the condition is false
526 alignStr += 2;
527 unsigned long long alignValue;
528 if (llvm::getAsUnsignedInteger(alignStr, 16, alignValue)) {
35
Assuming the condition is false
36
Taking false branch
529 diagnostics << "error: -sectalign alignment value '"
530 << alignStr << "' not a valid number\n";
531 return false;
532 }
533 uint16_t align = 1 << llvm::countTrailingZeros(alignValue);
37
The result of the left shift is undefined due to shifting by '64', which is greater or equal to the width of type 'int'
534 if (!llvm::isPowerOf2_64(alignValue)) {
535 diagnostics << "warning: alignment for '-sectalign "
536 << segName << " " << sectName
537 << llvm::format(" 0x%llX", alignValue)
538 << "' is not a power of two, using "
539 << llvm::format("0x%08X", align) << "\n";
540 }
541 ctx.addSectionAlignment(segName, sectName, align);
542 }
543
544 // Handle -mllvm
545 for (auto &llvmArg : parsedArgs.filtered(OPT_mllvm)) {
546 ctx.appendLLVMOption(llvmArg->getValue());
547 }
548
549 // Handle -print_atoms
550 if (parsedArgs.getLastArg(OPT_print_atoms))
551 ctx.setPrintAtoms();
552
553 // Handle -t (trace) option.
554 if (parsedArgs.getLastArg(OPT_t))
555 ctx.setLogInputFiles(true);
556
557 // Handle -demangle option.
558 if (parsedArgs.getLastArg(OPT_demangle))
559 ctx.setDemangleSymbols(true);
560
561 // Handle -keep_private_externs
562 if (parsedArgs.getLastArg(OPT_keep_private_externs)) {
563 ctx.setKeepPrivateExterns(true);
564 if (ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
565 diagnostics << "warning: -keep_private_externs only used in -r mode\n";
566 }
567
568 // Handle -dependency_info <path> used by Xcode.
569 if (llvm::opt::Arg *depInfo = parsedArgs.getLastArg(OPT_dependency_info)) {
570 if (std::error_code ec = ctx.createDependencyFile(depInfo->getValue())) {
571 diagnostics << "warning: " << ec.message()
572 << ", processing '-dependency_info "
573 << depInfo->getValue()
574 << "'\n";
575 }
576 }
577
578 // In -test_file_usage mode, we'll be given an explicit list of paths that
579 // exist. We'll also be expected to print out information about how we located
580 // libraries and so on that the user specified, but not to actually do any
581 // linking.
582 if (parsedArgs.getLastArg(OPT_test_file_usage)) {
583 ctx.setTestingFileUsage();
584
585 // With paths existing by fiat, linking is not going to end well.
586 ctx.setDoNothing(true);
587
588 // Only bother looking for an existence override if we're going to use it.
589 for (auto existingPath : parsedArgs.filtered(OPT_path_exists)) {
590 ctx.addExistingPathForDebug(existingPath->getValue());
591 }
592 }
593
594 // Register possible input file parsers.
595 if (!ctx.doNothing()) {
596 ctx.registry().addSupportMachOObjects(ctx);
597 ctx.registry().addSupportArchives(ctx.logInputFiles());
598 ctx.registry().addSupportYamlFiles();
599 }
600
601 // Now construct the set of library search directories, following ld64's
602 // baroque set of accumulated hacks. Mostly, the algorithm constructs
603 // { syslibroots } x { libpaths }
604 //
605 // Unfortunately, there are numerous exceptions:
606 // 1. Only absolute paths get modified by syslibroot options.
607 // 2. If there is just 1 -syslibroot, system paths not found in it are
608 // skipped.
609 // 3. If the last -syslibroot is "/", all of them are ignored entirely.
610 // 4. If { syslibroots } x path == {}, the original path is kept.
611 std::vector<StringRef> sysLibRoots;
612 for (auto syslibRoot : parsedArgs.filtered(OPT_syslibroot)) {
613 sysLibRoots.push_back(syslibRoot->getValue());
614 }
615 if (!sysLibRoots.empty()) {
616 // Ignore all if last -syslibroot is "/".
617 if (sysLibRoots.back() != "/")
618 ctx.setSysLibRoots(sysLibRoots);
619 }
620
621 // Paths specified with -L come first, and are not considered system paths for
622 // the case where there is precisely 1 -syslibroot.
623 for (auto libPath : parsedArgs.filtered(OPT_L)) {
624 ctx.addModifiedSearchDir(libPath->getValue());
625 }
626
627 // Process -F directories (where to look for frameworks).
628 for (auto fwPath : parsedArgs.filtered(OPT_F)) {
629 ctx.addFrameworkSearchDir(fwPath->getValue());
630 }
631
632 // -Z suppresses the standard search paths.
633 if (!parsedArgs.hasArg(OPT_Z)) {
634 ctx.addModifiedSearchDir("/usr/lib", true);
635 ctx.addModifiedSearchDir("/usr/local/lib", true);
636 ctx.addFrameworkSearchDir("/Library/Frameworks", true);
637 ctx.addFrameworkSearchDir("/System/Library/Frameworks", true);
638 }
639
640 // Now that we've constructed the final set of search paths, print out those
641 // search paths in verbose mode.
642 if (parsedArgs.getLastArg(OPT_v)) {
643 diagnostics << "Library search paths:\n";
644 for (auto path : ctx.searchDirs()) {
645 diagnostics << " " << path << '\n';
646 }
647 diagnostics << "Framework search paths:\n";
648 for (auto path : ctx.frameworkDirs()) {
649 diagnostics << " " << path << '\n';
650 }
651 }
652
653 // Handle -exported_symbols_list <file>
654 for (auto expFile : parsedArgs.filtered(OPT_exported_symbols_list)) {
655 if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) {
656 diagnostics << "error: -exported_symbols_list cannot be combined "
657 << "with -unexported_symbol[s_list]\n";
658 return false;
659 }
660 ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList);
661 if (std::error_code ec = parseExportsList(expFile->getValue(), ctx,
662 diagnostics)) {
663 diagnostics << "error: " << ec.message()
664 << ", processing '-exported_symbols_list "
665 << expFile->getValue()
666 << "'\n";
667 return false;
668 }
669 }
670
671 // Handle -exported_symbol <symbol>
672 for (auto symbol : parsedArgs.filtered(OPT_exported_symbol)) {
673 if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) {
674 diagnostics << "error: -exported_symbol cannot be combined "
675 << "with -unexported_symbol[s_list]\n";
676 return false;
677 }
678 ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList);
679 ctx.addExportSymbol(symbol->getValue());
680 }
681
682 // Handle -unexported_symbols_list <file>
683 for (auto expFile : parsedArgs.filtered(OPT_unexported_symbols_list)) {
684 if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) {
685 diagnostics << "error: -unexported_symbols_list cannot be combined "
686 << "with -exported_symbol[s_list]\n";
687 return false;
688 }
689 ctx.setExportMode(MachOLinkingContext::ExportMode::blackList);
690 if (std::error_code ec = parseExportsList(expFile->getValue(), ctx,
691 diagnostics)) {
692 diagnostics << "error: " << ec.message()
693 << ", processing '-unexported_symbols_list "
694 << expFile->getValue()
695 << "'\n";
696 return false;
697 }
698 }
699
700 // Handle -unexported_symbol <symbol>
701 for (auto symbol : parsedArgs.filtered(OPT_unexported_symbol)) {
702 if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) {
703 diagnostics << "error: -unexported_symbol cannot be combined "
704 << "with -exported_symbol[s_list]\n";
705 return false;
706 }
707 ctx.setExportMode(MachOLinkingContext::ExportMode::blackList);
708 ctx.addExportSymbol(symbol->getValue());
709 }
710
711 // Handle obosolete -multi_module and -single_module
712 if (llvm::opt::Arg *mod =
713 parsedArgs.getLastArg(OPT_multi_module, OPT_single_module)) {
714 if (mod->getOption().getID() == OPT_multi_module) {
715 diagnostics << "warning: -multi_module is obsolete and being ignored\n";
716 }
717 else {
718 if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) {
719 diagnostics << "warning: -single_module being ignored. "
720 "It is only for use when producing a dylib\n";
721 }
722 }
723 }
724
725 // Handle obsolete ObjC options: -objc_gc_compaction, -objc_gc, -objc_gc_only
726 if (parsedArgs.getLastArg(OPT_objc_gc_compaction)) {
727 diagnostics << "error: -objc_gc_compaction is not supported\n";
728 return false;
729 }
730
731 if (parsedArgs.getLastArg(OPT_objc_gc)) {
732 diagnostics << "error: -objc_gc is not supported\n";
733 return false;
734 }
735
736 if (parsedArgs.getLastArg(OPT_objc_gc_only)) {
737 diagnostics << "error: -objc_gc_only is not supported\n";
738 return false;
739 }
740
741 // Handle -pie or -no_pie
742 if (llvm::opt::Arg *pie = parsedArgs.getLastArg(OPT_pie, OPT_no_pie)) {
743 switch (ctx.outputMachOType()) {
744 case llvm::MachO::MH_EXECUTE:
745 switch (ctx.os()) {
746 case MachOLinkingContext::OS::macOSX:
747 if ((minOSVersion < 0x000A0500) &&
748 (pie->getOption().getID() == OPT_pie)) {
749 diagnostics << "-pie can only be used when targeting "
750 "Mac OS X 10.5 or later\n";
751 return false;
752 }
753 break;
754 case MachOLinkingContext::OS::iOS:
755 if ((minOSVersion < 0x00040200) &&
756 (pie->getOption().getID() == OPT_pie)) {
757 diagnostics << "-pie can only be used when targeting "
758 "iOS 4.2 or later\n";
759 return false;
760 }
761 break;
762 case MachOLinkingContext::OS::iOS_simulator:
763 if (pie->getOption().getID() == OPT_no_pie) {
764 diagnostics << "iOS simulator programs must be built PIE\n";
765 return false;
766 }
767 break;
768 case MachOLinkingContext::OS::unknown:
769 break;
770 }
771 ctx.setPIE(pie->getOption().getID() == OPT_pie);
772 break;
773 case llvm::MachO::MH_PRELOAD:
774 break;
775 case llvm::MachO::MH_DYLIB:
776 case llvm::MachO::MH_BUNDLE:
777 diagnostics << "warning: " << pie->getSpelling() << " being ignored. "
778 << "It is only used when linking main executables\n";
779 break;
780 default:
781 diagnostics << pie->getSpelling()
782 << " can only used when linking main executables\n";
783 return false;
784 }
785 }
786
787 // Handle -version_load_command or -no_version_load_command
788 {
789 bool flagOn = false;
790 bool flagOff = false;
791 if (auto *arg = parsedArgs.getLastArg(OPT_version_load_command,
792 OPT_no_version_load_command)) {
793 flagOn = arg->getOption().getID() == OPT_version_load_command;
794 flagOff = arg->getOption().getID() == OPT_no_version_load_command;
795 }
796
797 // default to adding version load command for dynamic code,
798 // static code must opt-in
799 switch (ctx.outputMachOType()) {
800 case llvm::MachO::MH_OBJECT:
801 ctx.setGenerateVersionLoadCommand(false);
802 break;
803 case llvm::MachO::MH_EXECUTE:
804 // dynamic executables default to generating a version load command,
805 // while static exectuables only generate it if required.
806 if (isStaticExecutable) {
807 if (flagOn)
808 ctx.setGenerateVersionLoadCommand(true);
809 } else {
810 if (!flagOff)
811 ctx.setGenerateVersionLoadCommand(true);
812 }
813 break;
814 case llvm::MachO::MH_PRELOAD:
815 case llvm::MachO::MH_KEXT_BUNDLE:
816 if (flagOn)
817 ctx.setGenerateVersionLoadCommand(true);
818 break;
819 case llvm::MachO::MH_DYLINKER:
820 case llvm::MachO::MH_DYLIB:
821 case llvm::MachO::MH_BUNDLE:
822 if (!flagOff)
823 ctx.setGenerateVersionLoadCommand(true);
824 break;
825 case llvm::MachO::MH_FVMLIB:
826 case llvm::MachO::MH_DYLDLINK:
827 case llvm::MachO::MH_DYLIB_STUB:
828 case llvm::MachO::MH_DSYM:
829 // We don't generate load commands for these file types, even if
830 // forced on.
831 break;
832 }
833 }
834
835 // Handle -function_starts or -no_function_starts
836 {
837 bool flagOn = false;
838 bool flagOff = false;
839 if (auto *arg = parsedArgs.getLastArg(OPT_function_starts,
840 OPT_no_function_starts)) {
841 flagOn = arg->getOption().getID() == OPT_function_starts;
842 flagOff = arg->getOption().getID() == OPT_no_function_starts;
843 }
844
845 // default to adding functions start for dynamic code, static code must
846 // opt-in
847 switch (ctx.outputMachOType()) {
848 case llvm::MachO::MH_OBJECT:
849 ctx.setGenerateFunctionStartsLoadCommand(false);
850 break;
851 case llvm::MachO::MH_EXECUTE:
852 // dynamic executables default to generating a version load command,
853 // while static exectuables only generate it if required.
854 if (isStaticExecutable) {
855 if (flagOn)
856 ctx.setGenerateFunctionStartsLoadCommand(true);
857 } else {
858 if (!flagOff)
859 ctx.setGenerateFunctionStartsLoadCommand(true);
860 }
861 break;
862 case llvm::MachO::MH_PRELOAD:
863 case llvm::MachO::MH_KEXT_BUNDLE:
864 if (flagOn)
865 ctx.setGenerateFunctionStartsLoadCommand(true);
866 break;
867 case llvm::MachO::MH_DYLINKER:
868 case llvm::MachO::MH_DYLIB:
869 case llvm::MachO::MH_BUNDLE:
870 if (!flagOff)
871 ctx.setGenerateFunctionStartsLoadCommand(true);
872 break;
873 case llvm::MachO::MH_FVMLIB:
874 case llvm::MachO::MH_DYLDLINK:
875 case llvm::MachO::MH_DYLIB_STUB:
876 case llvm::MachO::MH_DSYM:
877 // We don't generate load commands for these file types, even if
878 // forced on.
879 break;
880 }
881 }
882
883 // Handle -data_in_code_info or -no_data_in_code_info
884 {
885 bool flagOn = false;
886 bool flagOff = false;
887 if (auto *arg = parsedArgs.getLastArg(OPT_data_in_code_info,
888 OPT_no_data_in_code_info)) {
889 flagOn = arg->getOption().getID() == OPT_data_in_code_info;
890 flagOff = arg->getOption().getID() == OPT_no_data_in_code_info;
891 }
892
893 // default to adding data in code for dynamic code, static code must
894 // opt-in
895 switch (ctx.outputMachOType()) {
896 case llvm::MachO::MH_OBJECT:
897 if (!flagOff)
898 ctx.setGenerateDataInCodeLoadCommand(true);
899 break;
900 case llvm::MachO::MH_EXECUTE:
901 // dynamic executables default to generating a version load command,
902 // while static exectuables only generate it if required.
903 if (isStaticExecutable) {
904 if (flagOn)
905 ctx.setGenerateDataInCodeLoadCommand(true);
906 } else {
907 if (!flagOff)
908 ctx.setGenerateDataInCodeLoadCommand(true);
909 }
910 break;
911 case llvm::MachO::MH_PRELOAD:
912 case llvm::MachO::MH_KEXT_BUNDLE:
913 if (flagOn)
914 ctx.setGenerateDataInCodeLoadCommand(true);
915 break;
916 case llvm::MachO::MH_DYLINKER:
917 case llvm::MachO::MH_DYLIB:
918 case llvm::MachO::MH_BUNDLE:
919 if (!flagOff)
920 ctx.setGenerateDataInCodeLoadCommand(true);
921 break;
922 case llvm::MachO::MH_FVMLIB:
923 case llvm::MachO::MH_DYLDLINK:
924 case llvm::MachO::MH_DYLIB_STUB:
925 case llvm::MachO::MH_DSYM:
926 // We don't generate load commands for these file types, even if
927 // forced on.
928 break;
929 }
930 }
931
932 // Handle sdk_version
933 if (llvm::opt::Arg *arg = parsedArgs.getLastArg(OPT_sdk_version)) {
934 uint32_t sdkVersion = 0;
935 if (MachOLinkingContext::parsePackedVersion(arg->getValue(),
936 sdkVersion)) {
937 diagnostics << "error: malformed sdkVersion value\n";
938 return false;
939 }
940 ctx.setSdkVersion(sdkVersion);
941 } else if (ctx.generateVersionLoadCommand()) {
942 // If we don't have an sdk version, but were going to emit a load command
943 // with min_version, then we need to give an warning as we have no sdk
944 // version to put in that command.
945 // FIXME: We need to decide whether to make this an error.
946 diagnostics << "warning: -sdk_version is required when emitting "
947 "min version load command. "
948 "Setting sdk version to match provided min version\n";
949 ctx.setSdkVersion(ctx.osMinVersion());
950 }
951
952 // Handle source_version
953 if (llvm::opt::Arg *arg = parsedArgs.getLastArg(OPT_source_version)) {
954 uint64_t version = 0;
955 if (MachOLinkingContext::parsePackedVersion(arg->getValue(),
956 version)) {
957 diagnostics << "error: malformed source_version value\n";
958 return false;
959 }
960 ctx.setSourceVersion(version);
961 }
962
963 // Handle stack_size
964 if (llvm::opt::Arg *stackSize = parsedArgs.getLastArg(OPT_stack_size)) {
965 uint64_t stackSizeVal;
966 if (parseNumberBase16(stackSize->getValue(), stackSizeVal)) {
967 diagnostics << "error: stack_size expects a hex number\n";
968 return false;
969 }
970 if ((stackSizeVal % ctx.pageSize()) != 0) {
971 diagnostics << "error: stack_size must be a multiple of page size ("
972 << "0x" << llvm::utohexstr(ctx.pageSize()) << ")\n";
973 return false;
974 }
975
976 ctx.setStackSize(stackSizeVal);
977 }
978
979 // Handle debug info handling options: -S
980 if (parsedArgs.hasArg(OPT_S))
981 ctx.setDebugInfoMode(MachOLinkingContext::DebugInfoMode::noDebugMap);
982
983 // Handle -order_file <file>
984 for (auto orderFile : parsedArgs.filtered(OPT_order_file)) {
985 if (std::error_code ec = parseOrderFile(orderFile->getValue(), ctx,
986 diagnostics)) {
987 diagnostics << "error: " << ec.message()
988 << ", processing '-order_file "
989 << orderFile->getValue()
990 << "'\n";
991 return false;
992 }
993 }
994
995 // Handle -flat_namespace.
996 if (llvm::opt::Arg *ns =
997 parsedArgs.getLastArg(OPT_flat_namespace, OPT_twolevel_namespace)) {
998 if (ns->getOption().getID() == OPT_flat_namespace)
999 ctx.setUseFlatNamespace(true);
1000 }
1001
1002 // Handle -undefined
1003 if (llvm::opt::Arg *undef = parsedArgs.getLastArg(OPT_undefined)) {
1004 MachOLinkingContext::UndefinedMode UndefMode;
1005 if (StringRef(undef->getValue()).equals("error"))
1006 UndefMode = MachOLinkingContext::UndefinedMode::error;
1007 else if (StringRef(undef->getValue()).equals("warning"))
1008 UndefMode = MachOLinkingContext::UndefinedMode::warning;
1009 else if (StringRef(undef->getValue()).equals("suppress"))
1010 UndefMode = MachOLinkingContext::UndefinedMode::suppress;
1011 else if (StringRef(undef->getValue()).equals("dynamic_lookup"))
1012 UndefMode = MachOLinkingContext::UndefinedMode::dynamicLookup;
1013 else {
1014 diagnostics << "error: invalid option to -undefined "
1015 "[ warning | error | suppress | dynamic_lookup ]\n";
1016 return false;
1017 }
1018
1019 if (ctx.useFlatNamespace()) {
1020 // If we're using -flat_namespace then 'warning', 'suppress' and
1021 // 'dynamic_lookup' are all equivalent, so map them to 'suppress'.
1022 if (UndefMode != MachOLinkingContext::UndefinedMode::error)
1023 UndefMode = MachOLinkingContext::UndefinedMode::suppress;
1024 } else {
1025 // If we're using -twolevel_namespace then 'warning' and 'suppress' are
1026 // illegal. Emit a diagnostic if they've been (mis)used.
1027 if (UndefMode == MachOLinkingContext::UndefinedMode::warning ||
1028 UndefMode == MachOLinkingContext::UndefinedMode::suppress) {
1029 diagnostics << "error: can't use -undefined warning or suppress with "
1030 "-twolevel_namespace\n";
1031 return false;
1032 }
1033 }
1034
1035 ctx.setUndefinedMode(UndefMode);
1036 }
1037
1038 // Handle -no_objc_category_merging.
1039 if (parsedArgs.getLastArg(OPT_no_objc_category_merging))
1040 ctx.setMergeObjCCategories(false);
1041
1042 // Handle -rpath <path>
1043 if (parsedArgs.hasArg(OPT_rpath)) {
1044 switch (ctx.outputMachOType()) {
1045 case llvm::MachO::MH_EXECUTE:
1046 case llvm::MachO::MH_DYLIB:
1047 case llvm::MachO::MH_BUNDLE:
1048 if (!ctx.minOS("10.5", "2.0")) {
1049 if (ctx.os() == MachOLinkingContext::OS::macOSX) {
1050 diagnostics << "error: -rpath can only be used when targeting "
1051 "OS X 10.5 or later\n";
1052 } else {
1053 diagnostics << "error: -rpath can only be used when targeting "
1054 "iOS 2.0 or later\n";
1055 }
1056 return false;
1057 }
1058 break;
1059 default:
1060 diagnostics << "error: -rpath can only be used when creating "
1061 "a dynamic final linked image\n";
1062 return false;
1063 }
1064
1065 for (auto rPath : parsedArgs.filtered(OPT_rpath)) {
1066 ctx.addRpath(rPath->getValue());
1067 }
1068 }
1069
1070 // Parse the LLVM options before we process files in case the file handling
1071 // makes use of things like DEBUG().
1072 parseLLVMOptions(ctx);
1073
1074 // Handle input files and sectcreate.
1075 for (auto &arg : parsedArgs) {
1076 bool upward;
1077 llvm::Optional<StringRef> resolvedPath;
1078 switch (arg->getOption().getID()) {
1079 default:
1080 continue;
1081 case OPT_INPUT:
1082 addFile(arg->getValue(), ctx, globalWholeArchive, false, diagnostics);
1083 break;
1084 case OPT_upward_library:
1085 addFile(arg->getValue(), ctx, false, true, diagnostics);
1086 break;
1087 case OPT_force_load:
1088 addFile(arg->getValue(), ctx, true, false, diagnostics);
1089 break;
1090 case OPT_l:
1091 case OPT_upward_l:
1092 upward = (arg->getOption().getID() == OPT_upward_l);
1093 resolvedPath = ctx.searchLibrary(arg->getValue());
1094 if (!resolvedPath) {
1095 diagnostics << "Unable to find library for " << arg->getSpelling()
1096 << arg->getValue() << "\n";
1097 return false;
1098 } else if (ctx.testingFileUsage()) {
1099 diagnostics << "Found " << (upward ? "upward " : " ") << "library "
1100 << canonicalizePath(resolvedPath.getValue()) << '\n';
1101 }
1102 addFile(resolvedPath.getValue(), ctx, globalWholeArchive,
1103 upward, diagnostics);
1104 break;
1105 case OPT_framework:
1106 case OPT_upward_framework:
1107 upward = (arg->getOption().getID() == OPT_upward_framework);
1108 resolvedPath = ctx.findPathForFramework(arg->getValue());
1109 if (!resolvedPath) {
1110 diagnostics << "Unable to find framework for "
1111 << arg->getSpelling() << " " << arg->getValue() << "\n";
1112 return false;
1113 } else if (ctx.testingFileUsage()) {
1114 diagnostics << "Found " << (upward ? "upward " : " ") << "framework "
1115 << canonicalizePath(resolvedPath.getValue()) << '\n';
1116 }
1117 addFile(resolvedPath.getValue(), ctx, globalWholeArchive,
1118 upward, diagnostics);
1119 break;
1120 case OPT_filelist:
1121 if (auto ec = loadFileList(arg->getValue(),
1122 ctx, globalWholeArchive,
1123 diagnostics)) {
1124 handleAllErrors(std::move(ec), [&](const llvm::ErrorInfoBase &EI) {
1125 diagnostics << "error: ";
1126 EI.log(diagnostics);
1127 diagnostics << ", processing '-filelist " << arg->getValue() << "'\n";
1128 });
1129 return false;
1130 }
1131 break;
1132 case OPT_sectcreate: {
1133 const char* seg = arg->getValue(0);
1134 const char* sect = arg->getValue(1);
1135 const char* fileName = arg->getValue(2);
1136
1137 ErrorOr<std::unique_ptr<MemoryBuffer>> contentOrErr =
1138 MemoryBuffer::getFile(fileName);
1139
1140 if (!contentOrErr) {
1141 diagnostics << "error: can't open -sectcreate file " << fileName << "\n";
1142 return false;
1143 }
1144
1145 ctx.addSectCreateSection(seg, sect, std::move(*contentOrErr));
1146 }
1147 break;
1148 }
1149 }
1150
1151 if (ctx.getNodes().empty()) {
1152 diagnostics << "No input files\n";
1153 return false;
1154 }
1155
1156 // Validate the combination of options used.
1157 return ctx.validate(diagnostics);
1158}
1159
1160static void createFiles(MachOLinkingContext &ctx, bool Implicit) {
1161 std::vector<std::unique_ptr<File>> Files;
1162 if (Implicit)
1163 ctx.createImplicitFiles(Files);
1164 else
1165 ctx.createInternalFiles(Files);
1166 for (auto i = Files.rbegin(), e = Files.rend(); i != e; ++i) {
1167 auto &members = ctx.getNodes();
1168 members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
1169 }
1170}
1171
1172/// This is where the link is actually performed.
1173bool link(llvm::ArrayRef<const char *> args, raw_ostream &diagnostics) {
1174 MachOLinkingContext ctx;
1175 if (!parse(args, ctx, diagnostics))
1176 return false;
1177 if (ctx.doNothing())
1178 return true;
1179 if (ctx.getNodes().empty())
1180 return false;
1181
1182 for (std::unique_ptr<Node> &ie : ctx.getNodes())
1183 if (FileNode *node = dyn_cast<FileNode>(ie.get()))
1184 node->getFile()->parse();
1185
1186 createFiles(ctx, false /* Implicit */);
1187
1188 // Give target a chance to add files
1189 createFiles(ctx, true /* Implicit */);
1190
1191 // Give target a chance to postprocess input files.
1192 // Mach-O uses this chance to move all object files before library files.
1193 ctx.finalizeInputFiles();
1194
1195 // Do core linking.
1196 ScopedTask resolveTask(getDefaultDomain(), "Resolve");
1197 Resolver resolver(ctx);
1198 if (!resolver.resolve())
1199 return false;
1200 SimpleFile *merged = nullptr;
1201 {
1202 std::unique_ptr<SimpleFile> mergedFile = resolver.resultFile();
1203 merged = mergedFile.get();
1204 auto &members = ctx.getNodes();
1205 members.insert(members.begin(),
1206 llvm::make_unique<FileNode>(std::move(mergedFile)));
1207 }
1208 resolveTask.end();
1209
1210 // Run passes on linked atoms.
1211 ScopedTask passTask(getDefaultDomain(), "Passes");
1212 PassManager pm;
1213 ctx.addPasses(pm);
1214 if (auto ec = pm.runOnFile(*merged)) {
1215 // FIXME: This should be passed to logAllUnhandledErrors but it needs
1216 // to be passed a Twine instead of a string.
1217 diagnostics << "Failed to run passes on file '" << ctx.outputPath()
1218 << "': ";
1219 logAllUnhandledErrors(std::move(ec), diagnostics, std::string());
1220 return false;
1221 }
1222
1223 passTask.end();
1224
1225 // Give linked atoms to Writer to generate output file.
1226 ScopedTask writeTask(getDefaultDomain(), "Write");
1227 if (auto ec = ctx.writeFile(*merged)) {
1228 // FIXME: This should be passed to logAllUnhandledErrors but it needs
1229 // to be passed a Twine instead of a string.
1230 diagnostics << "Failed to write file '" << ctx.outputPath() << "': ";
1231 logAllUnhandledErrors(std::move(ec), diagnostics, std::string());
1232 return false;
1233 }
1234
1235 return true;
1236}
1237
1238} // end namespace mach_o
1239} // end namespace lld