blob: 8daf65fcee83356978a72ec0722715b761e4c2e0 [file] [log] [blame]
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001//===- llvm-mcld.cpp ------------------------------------------------------===//
2//
3// The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Shih-wei Liao22add6f2012-12-15 17:21:00 -08009#include <mcld/Module.h>
10#include <mcld/LinkerConfig.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070011#include <mcld/Target/TargetMachine.h>
12#include <mcld/Support/TargetSelect.h>
13#include <mcld/Support/TargetRegistry.h>
14#include <mcld/Support/CommandLine.h>
Zonr Changaffc1502012-07-16 14:28:23 +080015#include <mcld/Support/Path.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070016#include <mcld/Support/RealPath.h>
Zonr Changaffc1502012-07-16 14:28:23 +080017#include <mcld/Support/MsgHandling.h>
Shih-wei Liao22add6f2012-12-15 17:21:00 -080018#include <mcld/Support/FileHandle.h>
Zonr Changaffc1502012-07-16 14:28:23 +080019#include <mcld/Support/FileSystem.h>
20#include <mcld/Support/raw_ostream.h>
Shih-wei Liao22add6f2012-12-15 17:21:00 -080021#include <mcld/Support/ToolOutputFile.h>
Zonr Changaffc1502012-07-16 14:28:23 +080022#include <mcld/LD/DiagnosticLineInfo.h>
23#include <mcld/LD/TextDiagnosticPrinter.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070024
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070025#include <llvm/PassManager.h>
26#include <llvm/Pass.h>
Shih-wei Liao86036a32013-01-14 19:16:03 -080027#include <llvm/IR/Module.h>
28#include <llvm/IR/DataLayout.h>
29#include <llvm/IR/LLVMContext.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070030#include <llvm/ADT/Triple.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070031#include <llvm/MC/SubtargetFeature.h>
32#include <llvm/Support/CommandLine.h>
33#include <llvm/Support/Debug.h>
34#include <llvm/Support/FormattedStream.h>
35#include <llvm/Support/Host.h>
36#include <llvm/Support/IRReader.h>
37#include <llvm/Support/ManagedStatic.h>
Zonr Changaffc1502012-07-16 14:28:23 +080038#include <llvm/Support/Signals.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070039#include <llvm/Support/TargetRegistry.h>
40#include <llvm/Support/TargetSelect.h>
Zonr Changaffc1502012-07-16 14:28:23 +080041#include <llvm/Support/Process.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070042#include <llvm/Target/TargetMachine.h>
43
Shih-wei Liao22add6f2012-12-15 17:21:00 -080044#if defined(HAVE_UNISTD_H)
45# include <unistd.h>
46#endif
47
48#if defined(_MSC_VER)
49#include <io.h>
50#ifndef STDIN_FILENO
51# define STDIN_FILENO 0
52#endif
53#ifndef STDOUT_FILENO
54# define STDOUT_FILENO 1
55#endif
56#ifndef STDERR_FILENO
57# define STDERR_FILENO 2
58#endif
59#endif
60
61
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070062using namespace llvm;
63
64#ifdef ENABLE_UNITTEST
65#include <gtest.h>
66
67static cl::opt<bool>
68UnitTest("unittest", cl::desc("do unit test") );
69
70int unit_test( int argc, char* argv[] )
71{
72 testing::InitGoogleTest( &argc, argv );
73 return RUN_ALL_TESTS();
74}
75
76#endif
77
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070078// General options for llc. Other pass-specific options are specified
79// within the corresponding llc passes, and target-specific options
80// and back-end code generation options are specified with the target machine.
81//
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070082// Determine optimization level.
83static cl::opt<char>
84OptLevel("O",
85 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
86 "(default = '-O2')"),
87 cl::Prefix,
88 cl::ZeroOrMore,
89 cl::init(' '));
90
91static cl::opt<std::string>
92TargetTriple("mtriple", cl::desc("Override target triple for module"));
93
94static cl::opt<std::string>
95MArch("march", cl::desc("Architecture to generate code for (see --version)"));
96
97static cl::opt<std::string>
98MCPU("mcpu",
99 cl::desc("Target a specific cpu type (-mcpu=help for details)"),
100 cl::value_desc("cpu-name"),
101 cl::init(""));
102
103static cl::list<std::string>
104MAttrs("mattr",
105 cl::CommaSeparated,
106 cl::desc("Target specific attributes (-mattr=help for details)"),
107 cl::value_desc("a1,+a2,-a3,..."));
108
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700109static cl::opt<llvm::CodeModel::Model>
110CMModel("code-model",
111 cl::desc("Choose code model"),
112 cl::init(CodeModel::Default),
113 cl::values(clEnumValN(CodeModel::Default, "default",
114 "Target default code model"),
115 clEnumValN(CodeModel::Small, "small",
116 "Small code model"),
117 clEnumValN(CodeModel::Kernel, "kernel",
118 "Kernel code model"),
119 clEnumValN(CodeModel::Medium, "medium",
120 "Medium code model"),
121 clEnumValN(CodeModel::Large, "large",
122 "Large code model"),
123 clEnumValEnd));
124
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700125cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
126 cl::desc("Do not verify input module"));
127
128static cl::opt<bool>
129EnableFPMAD("enable-fp-mad",
130 cl::desc("Enable less precise MAD instructions to be generated"),
131 cl::init(false));
132
133static cl::opt<bool>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700134DisableFPElim("disable-fp-elim",
135 cl::desc("Disable frame pointer elimination optimization"),
136 cl::init(false));
137
138static cl::opt<bool>
139DisableFPElimNonLeaf("disable-non-leaf-fp-elim",
140 cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"),
141 cl::init(false));
142
Shih-wei Liaocedee4b2012-08-02 23:13:03 -0700143static cl::opt<llvm::FPOpFusion::FPOpFusionMode>
144FuseFPOps("fuse-fp-ops",
145 cl::desc("Enable aggresive formation of fused FP ops"),
146 cl::init(FPOpFusion::Standard),
147 cl::values(
148 clEnumValN(FPOpFusion::Fast, "fast",
149 "Fuse FP ops whenever profitable"),
150 clEnumValN(FPOpFusion::Standard, "standard",
151 "Only fuse 'blessed' FP ops."),
152 clEnumValN(FPOpFusion::Strict, "strict",
153 "Only fuse FP ops when the result won't be effected."),
154 clEnumValEnd));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700155
156static cl::opt<bool>
157EnableUnsafeFPMath("enable-unsafe-fp-math",
158 cl::desc("Enable optimizations that may decrease FP precision"),
159 cl::init(false));
160
161static cl::opt<bool>
162EnableNoInfsFPMath("enable-no-infs-fp-math",
163 cl::desc("Enable FP math optimizations that assume no +-Infs"),
164 cl::init(false));
165
166static cl::opt<bool>
167EnableNoNaNsFPMath("enable-no-nans-fp-math",
168 cl::desc("Enable FP math optimizations that assume no NaNs"),
169 cl::init(false));
170
171static cl::opt<bool>
172EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math",
173 cl::Hidden,
174 cl::desc("Force codegen to assume rounding mode can change dynamically"),
175 cl::init(false));
176
177static cl::opt<bool>
178GenerateSoftFloatCalls("soft-float",
179 cl::desc("Generate software floating point library calls"),
180 cl::init(false));
181
182static cl::opt<llvm::FloatABI::ABIType>
183FloatABIForCalls("float-abi",
184 cl::desc("Choose float ABI type"),
185 cl::init(FloatABI::Default),
186 cl::values(
187 clEnumValN(FloatABI::Default, "default",
188 "Target default float ABI type"),
189 clEnumValN(FloatABI::Soft, "soft",
190 "Soft float ABI (implied by -soft-float)"),
191 clEnumValN(FloatABI::Hard, "hard",
192 "Hard float ABI (uses FP registers)"),
193 clEnumValEnd));
194
195static cl::opt<bool>
196DontPlaceZerosInBSS("nozero-initialized-in-bss",
197 cl::desc("Don't place zero-initialized symbols into bss section"),
198 cl::init(false));
199
200static cl::opt<bool>
201EnableJITExceptionHandling("jit-enable-eh",
202 cl::desc("Emit exception handling information"),
203 cl::init(false));
204
205// In debug builds, make this default to true.
206#ifdef NDEBUG
207#define EMIT_DEBUG false
208#else
209#define EMIT_DEBUG true
210#endif
211static cl::opt<bool>
212EmitJitDebugInfo("jit-emit-debug",
213 cl::desc("Emit debug information to debugger"),
214 cl::init(EMIT_DEBUG));
215#undef EMIT_DEBUG
216
217static cl::opt<bool>
218EmitJitDebugInfoToDisk("jit-emit-debug-to-disk",
219 cl::Hidden,
220 cl::desc("Emit debug info objfiles to disk"),
221 cl::init(false));
222
223static cl::opt<bool>
224EnableGuaranteedTailCallOpt("tailcallopt",
225 cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."),
226 cl::init(false));
227
228static cl::opt<unsigned>
229OverrideStackAlignment("stack-alignment",
230 cl::desc("Override default stack alignment"),
231 cl::init(0));
232
233static cl::opt<bool>
234EnableRealignStack("realign-stack",
235 cl::desc("Realign stack if needed"),
236 cl::init(true));
237
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700238static cl::opt<std::string>
239TrapFuncName("trap-func", cl::Hidden,
240 cl::desc("Emit a call to trap function rather than a trap instruction"),
241 cl::init(""));
242
243static cl::opt<bool>
244SegmentedStacks("segmented-stacks",
245 cl::desc("Use segmented stacks if possible."),
246 cl::init(false));
247
248//===----------------------------------------------------------------------===//
249// Command Line Options
250// There are four kinds of command line options:
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800251// 1. Bitcode option. Used to represent a bitcode.
252// 2. Attribute options. Attributes describes the input file after them. For
253// example, --as-needed affects the input file after this option. Attribute
254// options are not attributes. Attribute options are the options that is
255// used to define a legal attribute.
256// 3. Scripting options, Used to represent a subset of link scripting
257// language, such as --defsym.
258// 4. General options. (the rest of options)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700259//===----------------------------------------------------------------------===//
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800260// Bitcode Options
261//===----------------------------------------------------------------------===//
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700262static cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> >
Zonr Changaffc1502012-07-16 14:28:23 +0800263ArgBitcodeFilename("dB",
264 cl::desc("set default bitcode"),
265 cl::value_desc("bitcode"));
266
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800267//===----------------------------------------------------------------------===//
268// General Options
269//===----------------------------------------------------------------------===//
Zonr Changaffc1502012-07-16 14:28:23 +0800270static cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> >
271ArgOutputFilename("o",
272 cl::desc("Output filename"),
273 cl::value_desc("filename"));
274
275static cl::alias
276AliasOutputFilename("output",
277 cl::desc("alias for -o"),
278 cl::aliasopt(ArgOutputFilename));
279
280static cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> >
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700281ArgSysRoot("sysroot",
282 cl::desc("Use directory as the location of the sysroot, overriding the configure-time default."),
283 cl::value_desc("directory"),
284 cl::ValueRequired);
285
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800286static cl::list<std::string, bool, llvm::cl::SearchDirParser>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700287ArgSearchDirList("L",
288 cl::ZeroOrMore,
289 cl::desc("Add path searchdir to the list of paths that ld will search for archive libraries and ld control scripts."),
290 cl::value_desc("searchdir"),
291 cl::Prefix);
292
293static cl::alias
294ArgSearchDirListAlias("library-path",
295 cl::desc("alias for -L"),
296 cl::aliasopt(ArgSearchDirList));
297
298static cl::opt<bool>
299ArgTrace("t",
300 cl::desc("Print the names of the input files as ld processes them."));
301
302static cl::alias
303ArgTraceAlias("trace",
304 cl::desc("alias for -t"),
305 cl::aliasopt(ArgTrace));
306
Zonr Changaffc1502012-07-16 14:28:23 +0800307static cl::opt<int>
308ArgVerbose("verbose",
309 cl::init(-1),
310 cl::desc("Display the version number for ld and list the linker emulations supported."));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700311
Zonr Changaffc1502012-07-16 14:28:23 +0800312static cl::opt<bool>
313ArgVersion("V",
314 cl::init(false),
315 cl::desc("Display the version number for MCLinker."));
316
317static cl::opt<int>
318ArgMaxErrorNum("error-limit",
319 cl::init(-1),
320 cl::desc("limits the maximum number of erros."));
321
322static cl::opt<int>
323ArgMaxWarnNum("warning-limit",
324 cl::init(-1),
325 cl::desc("limits the maximum number of warnings."));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700326
327static cl::opt<std::string>
328ArgEntry("e",
329 cl::desc("Use entry as the explicit symbol for beginning execution of your program."),
330 cl::value_desc("entry"),
331 cl::ValueRequired);
332
333static cl::alias
334ArgEntryAlias("entry",
335 cl::desc("alias for -e"),
336 cl::aliasopt(ArgEntry));
337
338static cl::opt<bool>
339ArgBsymbolic("Bsymbolic",
340 cl::desc("Bind references within the shared library."),
341 cl::init(false));
342
Zonr Changaffc1502012-07-16 14:28:23 +0800343static cl::opt<bool>
344ArgBgroup("Bgroup",
345 cl::desc("Info the dynamic linker to perform lookups only inside the group."),
346 cl::init(false));
347
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700348static cl::opt<std::string>
349ArgSOName("soname",
350 cl::desc("Set internal name of shared library"),
351 cl::value_desc("name"));
352
Zonr Changaffc1502012-07-16 14:28:23 +0800353static cl::opt<bool>
354ArgNoUndefined("no-undefined",
355 cl::desc("Do not allow unresolved references"),
356 cl::init(false));
357
358static cl::opt<bool>
359ArgAllowMulDefs("allow-multiple-definition",
360 cl::desc("Allow multiple definition"),
361 cl::init(false));
362
363static cl::opt<bool>
364ArgEhFrameHdr("eh-frame-hdr",
365 cl::desc("Request creation of \".eh_frame_hdr\" section and ELF \"PT_GNU_EH_FRAME\" segment header."),
366 cl::init(false));
367
368static cl::list<mcld::ZOption, bool, llvm::cl::parser<mcld::ZOption> >
369ArgZOptionList("z",
370 cl::ZeroOrMore,
371 cl::desc("The -z options for GNU ld compatibility."),
372 cl::value_desc("keyword"),
373 cl::Prefix);
374
375cl::opt<mcld::CodeGenFileType>
376ArgFileType("filetype", cl::init(mcld::CGFT_EXEFile),
377 cl::desc("Choose a file type (not all types are supported by all targets):"),
378 cl::values(
379 clEnumValN(mcld::CGFT_ASMFile, "asm",
380 "Emit an assembly ('.s') file"),
381 clEnumValN(mcld::CGFT_OBJFile, "obj",
382 "Emit a relocatable object ('.o') file"),
383 clEnumValN(mcld::CGFT_DSOFile, "dso",
384 "Emit an dynamic shared object ('.so') file"),
385 clEnumValN(mcld::CGFT_EXEFile, "exe",
386 "Emit a executable ('.exe') file"),
387 clEnumValN(mcld::CGFT_NULLFile, "null",
388 "Emit nothing, for performance testing"),
389 clEnumValEnd));
390
391static cl::opt<bool>
392ArgShared("shared",
393 cl::desc("Create a shared library."),
394 cl::init(false));
395
396static cl::alias
397ArgSharedAlias("Bshareable",
398 cl::desc("alias for -shared"),
399 cl::aliasopt(ArgShared));
400
401static cl::opt<bool>
402ArgPIE("pie",
403 cl::desc("Emit a position-independent executable file"),
404 cl::init(false));
405
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800406static cl::opt<bool>
407ArgRelocatable("relocatable",
408 cl::desc("Generate relocatable output"),
409 cl::init(false));
410
411static cl::alias
412ArgRelocatableAlias("r",
413 cl::desc("alias for --relocatable"),
414 cl::aliasopt(ArgRelocatable));
415
Zonr Changaffc1502012-07-16 14:28:23 +0800416static cl::opt<Reloc::Model>
417ArgRelocModel("relocation-model",
418 cl::desc("Choose relocation model"),
419 cl::init(Reloc::Default),
420 cl::values(
421 clEnumValN(Reloc::Default, "default",
422 "Target default relocation model"),
423 clEnumValN(Reloc::Static, "static",
424 "Non-relocatable code"),
425 clEnumValN(Reloc::PIC_, "pic",
426 "Fully relocatable, position independent code"),
427 clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
428 "Relocatable external references, non-relocatable code"),
429 clEnumValEnd));
430
431static cl::opt<bool>
432ArgFPIC("fPIC",
433 cl::desc("Set relocation model to pic. The same as -relocation-model=pic."),
434 cl::init(false));
435
436static cl::opt<std::string>
437ArgDyld("dynamic-linker",
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800438 cl::ZeroOrMore,
Zonr Changaffc1502012-07-16 14:28:23 +0800439 cl::desc("Set the name of the dynamic linker."),
440 cl::value_desc("Program"));
441
442namespace color {
443enum Color {
444 Never,
445 Always,
446 Auto
447};
448} // namespace of color
449
450static cl::opt<color::Color>
451ArgColor("color",
452 cl::value_desc("WHEN"),
453 cl::desc("Surround the result strings with the marker"),
454 cl::init(color::Auto),
455 cl::values(
456 clEnumValN(color::Never, "never",
457 "do not surround result strings"),
458 clEnumValN(color::Always, "always",
459 "always surround result strings, even the output is a plain file"),
460 clEnumValN(color::Auto, "auto",
461 "surround result strings only if the output is a tty"),
462 clEnumValEnd));
463
Stephen Hines6f757552013-03-04 19:51:03 -0800464static cl::opt<bool>
465ArgDiscardLocals("discard-locals",
466 cl::desc("Delete all temporary local symbols."),
467 cl::init(false));
468
469static cl::alias
470ArgDiscardLocalsAlias("X",
471 cl::desc("alias for --discard-locals"),
472 cl::aliasopt(ArgDiscardLocals));
473
474static cl::opt<bool>
475ArgDiscardAll("discard-all",
476 cl::desc("Delete all local symbols."),
477 cl::init(false));
478
479static cl::alias
480ArgDiscardAllAlias("x",
481 cl::desc("alias for --discard-all"),
482 cl::aliasopt(ArgDiscardAll));
483
484static cl::opt<bool>
485ArgStripDebug("strip-debug",
486 cl::desc("Omit debugger symbol information from the output file."),
487 cl::init(false));
488
489static cl::alias
490ArgStripDebugAlias("S",
491 cl::desc("alias for --strip-debug"),
492 cl::aliasopt(ArgStripDebug));
493
494static cl::opt<bool>
495ArgStripAll("strip-all",
496 cl::desc("Omit all symbol information from the output file."),
497 cl::init(false));
498
499static cl::alias
500ArgStripAllAlias("s",
501 cl::desc("alias for --strip-all"),
502 cl::aliasopt(ArgStripAll));
503
504static cl::opt<bool>
505ArgNMagic("nmagic",
506 cl::desc("Do not page align data"),
507 cl::init(false));
508
509static cl::alias
510ArgNMagicAlias("n",
511 cl::desc("alias for --nmagic"),
512 cl::aliasopt(ArgNMagic));
513
514static cl::opt<bool>
515ArgOMagic("omagic",
516 cl::desc("Do not page align data, do not make text readonly"),
517 cl::init(false));
518
519static cl::alias
520ArgOMagicAlias("N",
521 cl::desc("alias for --omagic"),
522 cl::aliasopt(ArgOMagic));
523
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800524/// @{
525/// @name FIXME: begin of unsupported options
526/// @}
527static cl::opt<bool>
528ArgGCSections("gc-sections",
529 cl::desc("Enable garbage collection of unused input sections."),
530 cl::init(false));
531
532static cl::opt<bool>
533ArgNoGCSections("no-gc-sections",
534 cl::desc("disable garbage collection of unused input sections."),
535 cl::init(false));
536
537namespace icf {
538enum Mode {
539 None,
540 All,
541 Safe
542};
543} // namespace of icf
544
545static cl::opt<icf::Mode>
546ArgICF("icf",
Stephen Hines6f757552013-03-04 19:51:03 -0800547 cl::ZeroOrMore,
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800548 cl::desc("Identical Code Folding"),
549 cl::init(icf::None),
550 cl::values(
551 clEnumValN(icf::None, "none",
552 "do not perform cold folding"),
553 clEnumValN(icf::All, "all",
554 "always preform cold folding"),
555 clEnumValN(icf::Safe, "safe",
556 "Folds ctors, dtors and functions whose pointers are definitely not taken."),
557 clEnumValEnd));
558
559// FIXME: add this to target options?
560static cl::opt<bool>
561ArgFIXCA8("fix-cortex-a8",
562 cl::desc("Enable Cortex-A8 Thumb-2 branch erratum fix"),
563 cl::init(false));
564
565static cl::opt<bool>
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800566ArgExportDynamic("export-dynamic",
567 cl::desc("Export all dynamic symbols"),
568 cl::init(false));
569
570static cl::alias
571ArgExportDynamicAlias("E",
572 cl::desc("alias for --export-dynamic"),
573 cl::aliasopt(ArgExportDynamic));
574
575static cl::opt<std::string>
576ArgEmulation("m",
577 cl::desc("Set GNU linker emulation"),
578 cl::value_desc("emulation"));
579
Stephen Hines6f757552013-03-04 19:51:03 -0800580static cl::list<std::string, bool, llvm::cl::SearchDirParser>
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800581ArgRuntimePathLink("rpath-link",
Stephen Hines6f757552013-03-04 19:51:03 -0800582 cl::ZeroOrMore,
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800583 cl::desc("Add a directory to the link time library search path"),
584 cl::value_desc("dir"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700585
586static cl::list<std::string>
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800587ArgExcludeLIBS("exclude-libs",
588 cl::CommaSeparated,
589 cl::desc("Exclude libraries from automatic export"),
590 cl::value_desc("lib1,lib2,..."));
591
592static cl::opt<std::string>
593ArgBuildID("build-id",
594 cl::desc("Request creation of \".note.gnu.build-id\" ELF note section."),
595 cl::value_desc("style"));
596
597static cl::opt<std::string>
598ArgForceUndefined("u",
599 cl::desc("Force symbol to be undefined in the output file"),
600 cl::value_desc("symbol"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700601
602static cl::alias
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800603ArgForceUndefinedAlias("undefined",
604 cl::desc("alias for -u"),
605 cl::aliasopt(ArgForceUndefined));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700606
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800607static cl::opt<std::string>
608ArgVersionScript("version-script",
609 cl::desc("Version script."),
610 cl::value_desc("Version script"));
611
612static cl::opt<bool>
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800613ArgWarnCommon("warn-common",
614 cl::desc("warn common symbol"),
615 cl::init(false));
616
Stephen Hines6f757552013-03-04 19:51:03 -0800617static cl::opt<mcld::GeneralOptions::HashStyle>
618ArgHashStyle("hash-style", cl::init(mcld::GeneralOptions::SystemV),
619 cl::desc("Set the type of linker's hash table(s)."),
620 cl::values(
621 clEnumValN(mcld::GeneralOptions::SystemV, "sysv",
622 "classic ELF .hash section"),
623 clEnumValN(mcld::GeneralOptions::GNU, "gnu",
624 "new style GNU .gnu.hash section"),
625 clEnumValN(mcld::GeneralOptions::Both, "both",
626 "both the classic ELF and new style GNU hash tables"),
627 clEnumValEnd));
628
629static cl::opt<std::string>
630ArgFilter("F",
631 cl::desc("Filter for shared object symbol table"),
632 cl::value_desc("name"));
633
634static cl::alias
635ArgFilterAlias("filter",
636 cl::desc("alias for -F"),
637 cl::aliasopt(ArgFilterAlias));
638
639static cl::list<std::string>
640ArgAuxiliary("f",
641 cl::ZeroOrMore,
642 cl::desc("Auxiliary filter for shared object symbol table"),
643 cl::value_desc("name"));
644
645static cl::alias
646ArgAuxiliaryAlias("auxiliary",
647 cl::desc("alias for -f"),
648 cl::aliasopt(ArgAuxiliary));
649
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800650static cl::opt<bool>
Stephen Hines6f757552013-03-04 19:51:03 -0800651ArgEB("EB",
652 cl::desc("Link big-endian objects. This affects the default output format."),
653 cl::init(false));
654
655static cl::opt<bool>
656ArgEL("EL",
657 cl::desc("Link little-endian objects. This affects the default output format."),
658 cl::init(false));
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800659
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800660/// @{
661/// @name FIXME: end of unsupported options
662/// @}
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700663
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800664static cl::opt<bool>
Stephen Hines6f757552013-03-04 19:51:03 -0800665ArgNoStdlib("nostdlib",
666 cl::desc("Only search lib dirs explicitly specified on cmdline"),
667 cl::init(false));
668
669static cl::list<std::string, bool, llvm::cl::SearchDirParser>
670ArgRuntimePath("rpath",
671 cl::ZeroOrMore,
672 cl::desc("Add a directory to the runtime library search path"),
673 cl::value_desc("dir"));
674
675static cl::alias
676ArgRuntimePathAlias("R",
677 cl::desc("alias for --rpath"),
678 cl::aliasopt(ArgRuntimePath), cl::Prefix);
679
680static cl::opt<bool>
681ArgEnableNewDTags("enable-new-dtags",
682 cl::desc("Enable use of DT_RUNPATH and DT_FLAGS"),
683 cl::init(false));
684
685class FalseParser : public cl::parser<bool> {
686 const char *ArgStr;
687public:
688
689 // parse - Return true on error.
690 bool parse(cl::Option &O, StringRef ArgName, StringRef Arg, bool &Val) {
691 if (cl::parser<bool>::parse(O, ArgName, Arg, Val))
692 return false;
693 Val = false;
694 return false;
695 }
696};
697
698static bool ArgFatalWarnings;
699
700static cl::opt<bool, true, FalseParser>
701ArgNoFatalWarnings("no-fatal-warnings",
702 cl::location(ArgFatalWarnings),
703 cl::desc("do not turn warnings into errors"),
704 cl::init(false),
705 cl::ValueDisallowed);
706
707static cl::opt<bool, true>
708ArgFatalWarnings_("fatal-warnings",
709 cl::location(ArgFatalWarnings),
710 cl::desc("turn all warnings into errors"),
711 cl::init(false),
712 cl::ValueDisallowed);
713
714static cl::opt<bool>
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800715ArgWarnSharedTextrel("warn-shared-textrel",
716 cl::desc("Warn if adding DT_TEXTREL in a shared object."),
717 cl::init(false));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700718
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800719namespace format {
720enum Format {
721 Binary,
722 Unknown // decided by triple
723};
724} // namespace of format
725
726static cl::opt<format::Format>
727ArgFormat("b",
728 cl::value_desc("Format"),
729 cl::desc("set input format"),
730 cl::init(format::Unknown),
731 cl::values(
732 clEnumValN(format::Binary, "binary",
733 "read in binary machine code."),
734 clEnumValEnd));
735
736static cl::alias
737ArgFormatAlias("format",
738 cl::desc("alias for -b"),
739 cl::aliasopt(ArgFormat));
740
741static cl::opt<format::Format>
742ArgOFormat("oformat",
743 cl::value_desc("Format"),
744 cl::desc("set output format"),
745 cl::init(format::Unknown),
746 cl::values(
747 clEnumValN(format::Binary, "binary",
748 "generate binary machine code."),
749 clEnumValEnd));
750
751static cl::opt<bool>
752ArgDefineCommon("d",
753 cl::ZeroOrMore,
754 cl::desc("Define common symbol"),
755 cl::init(false));
756
757static cl::alias
758ArgDefineCommonAlias1("dc",
759 cl::desc("alias for -d"),
760 cl::aliasopt(ArgDefineCommon));
761
762static cl::alias
763ArgDefineCommonAlias2("dp",
764 cl::desc("alias for -d"),
765 cl::aliasopt(ArgDefineCommon));
766
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700767//===----------------------------------------------------------------------===//
768// Scripting Options
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800769//===----------------------------------------------------------------------===//
Zonr Changaffc1502012-07-16 14:28:23 +0800770static cl::list<std::string>
771ArgWrapList("wrap",
772 cl::ZeroOrMore,
773 cl::desc("Use a wrap function fo symbol."),
774 cl::value_desc("symbol"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700775
Zonr Changaffc1502012-07-16 14:28:23 +0800776static cl::list<std::string>
777ArgPortList("portable",
778 cl::ZeroOrMore,
779 cl::desc("Use a portable function fo symbol."),
780 cl::value_desc("symbol"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700781
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800782static cl::list<std::string>
783ArgAddressMapList("section-start",
784 cl::ZeroOrMore,
785 cl::desc("Locate a output section at the given absolute address"),
786 cl::value_desc("Set address of section"),
787 cl::Prefix);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700788
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800789static cl::opt<unsigned long long>
790ArgBssSegAddr("Tbss",
791 cl::desc("Set the address of the bss segment"),
792 cl::init(-1U));
793
794static cl::opt<unsigned long long>
795ArgDataSegAddr("Tdata",
796 cl::desc("Set the address of the data segment"),
797 cl::init(-1U));
798
799static cl::opt<unsigned long long>
800ArgTextSegAddr("Ttext",
801 cl::desc("Set the address of the text segment"),
802 cl::init(-1U));
803
804//===----------------------------------------------------------------------===//
805// non-member functions
806//===----------------------------------------------------------------------===//
Zonr Changaffc1502012-07-16 14:28:23 +0800807/// GetOutputStream - get the output stream.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800808static mcld::ToolOutputFile *GetOutputStream(const char* pTargetName,
809 Triple::OSType pOSType,
810 mcld::CodeGenFileType pFileType,
811 const mcld::sys::fs::Path& pInputFilename,
812 mcld::sys::fs::Path& pOutputFilename)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700813{
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700814 if (pOutputFilename.empty()) {
Zonr Changaffc1502012-07-16 14:28:23 +0800815 if (0 == pInputFilename.native().compare("-"))
816 pOutputFilename.assign("-");
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700817 else {
Zonr Changaffc1502012-07-16 14:28:23 +0800818 switch(pFileType) {
819 case mcld::CGFT_ASMFile: {
820 if (0 == pInputFilename.native().compare("-"))
821 pOutputFilename.assign("_out");
822 else
823 pOutputFilename.assign(pInputFilename.stem().native());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700824
Zonr Changaffc1502012-07-16 14:28:23 +0800825 if (0 == strcmp(pTargetName, "c"))
826 pOutputFilename.native() += ".cbe.c";
827 else if (0 == strcmp(pTargetName, "cpp"))
828 pOutputFilename.native() += ".cpp";
829 else
830 pOutputFilename.native() += ".s";
831 }
832 break;
833
834 case mcld::CGFT_OBJFile: {
835 if (0 == pInputFilename.native().compare("-"))
836 pOutputFilename.assign("_out");
837 else
838 pOutputFilename.assign(pInputFilename.stem().native());
839
840 if (pOSType == Triple::Win32)
841 pOutputFilename.native() += ".obj";
842 else
843 pOutputFilename.native() += ".o";
844 }
845 break;
846
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800847 case mcld::CGFT_PARTIAL: {
848 if (Triple::Win32 == pOSType) {
849 if (0 == pInputFilename.native().compare("-"))
850 pOutputFilename.assign("_out");
851 else
852 pOutputFilename.assign(pInputFilename.stem().native());
853 pOutputFilename.native() += ".obj";
854 }
855 else
856 pOutputFilename.assign("a.out");
857 }
858 break;
859
Zonr Changaffc1502012-07-16 14:28:23 +0800860 case mcld::CGFT_DSOFile: {
861 if (Triple::Win32 == pOSType) {
862 if (0 == pInputFilename.native().compare("-"))
863 pOutputFilename.assign("_out");
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700864 else
Zonr Changaffc1502012-07-16 14:28:23 +0800865 pOutputFilename.assign(pInputFilename.stem().native());
866 pOutputFilename.native() += ".dll";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700867 }
868 else
Zonr Changaffc1502012-07-16 14:28:23 +0800869 pOutputFilename.assign("a.out");
870 }
871 break;
872
873 case mcld::CGFT_EXEFile: {
874 if (Triple::Win32 == pOSType) {
875 if (0 == pInputFilename.native().compare("-"))
876 pOutputFilename.assign("_out");
877 else
878 pOutputFilename.assign(pInputFilename.stem().native());
879 pOutputFilename.native() += ".exe";
880 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700881 else
Zonr Changaffc1502012-07-16 14:28:23 +0800882 pOutputFilename.assign("a.out");
883 }
884 break;
885
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700886 case mcld::CGFT_NULLFile:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700887 break;
888 default:
Zonr Changaffc1502012-07-16 14:28:23 +0800889 llvm::report_fatal_error("Unknown output file type.\n");
890 } // end of switch
891 } // end of ! pInputFilename == "-"
892 } // end of if empty pOutputFilename
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700893
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800894 mcld::FileHandle::Permission permission;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700895 switch (pFileType) {
896 default: assert(0 && "Unknown file type");
897 case mcld::CGFT_ASMFile:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700898 case mcld::CGFT_OBJFile:
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800899 case mcld::CGFT_PARTIAL:
900 permission = 0644;
901 break;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700902 case mcld::CGFT_DSOFile:
903 case mcld::CGFT_EXEFile:
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800904 case mcld::CGFT_BINARY:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700905 case mcld::CGFT_NULLFile:
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800906 permission = 0755;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700907 break;
908 }
909
910 // Open the file.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800911 mcld::ToolOutputFile* result_output =
912 new mcld::ToolOutputFile(pOutputFilename,
913 mcld::FileHandle::ReadWrite |
914 mcld::FileHandle::Create |
915 mcld::FileHandle::Truncate,
916 permission);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700917
Zonr Changaffc1502012-07-16 14:28:23 +0800918 return result_output;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700919}
920
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800921/// ParseProgName - Parse program name
922/// This function simplifies cross-compiling by reading triple from the program
923/// name. For example, if the program name is `arm-linux-eabi-ld.mcld', we can
924/// get the triple is arm-linux-eabi by the program name.
925static void ParseProgName(const char *progname)
926{
927 static const char *suffixes[] = {
928 "ld",
929 "ld.mcld",
930 };
931
932 std::string ProgName(mcld::sys::fs::Path(progname).stem().native());
933
934 for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
935 if (ProgName == suffixes[i])
936 return;
937 }
938
939 StringRef ProgNameRef(ProgName);
940 StringRef Prefix;
941
942 for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
943 if (!ProgNameRef.endswith(suffixes[i]))
944 continue;
945
946 StringRef::size_type LastComponent = ProgNameRef.rfind('-',
947 ProgNameRef.size() - strlen(suffixes[i]));
948 if (LastComponent == StringRef::npos)
949 continue;
950 StringRef Prefix = ProgNameRef.slice(0, LastComponent);
951 std::string IgnoredError;
952 if (!llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError))
953 continue;
954 TargetTriple = Prefix.str();
955 return;
956 }
957}
958
Zonr Changaffc1502012-07-16 14:28:23 +0800959static bool ShouldColorize()
960{
961 const char* term = getenv("TERM");
962 return term && (0 != strcmp(term, "dumb"));
963}
964
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800965static bool ProcessLinkerOptionsFromCommand(mcld::LinkerConfig& pConfig) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700966 // ----- Set up General Options ----- //
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800967 // set up colorize
968 switch (ArgColor) {
969 case color::Never:
970 pConfig.options().setColor(false);
971 break;
972 case color::Always:
973 pConfig.options().setColor(true);
974 break;
975 case color::Auto:
976 bool color_option = ShouldColorize() &&
977 llvm::sys::Process::FileDescriptorIsDisplayed(STDOUT_FILENO);
978 pConfig.options().setColor(color_option);
979 break;
980 }
981
982 mcld::outs().setColor(pConfig.options().color());
983 mcld::errs().setColor(pConfig.options().color());
984
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700985 // set up soname
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800986 pConfig.options().setSOName(ArgSOName);
987
Stephen Hines6f757552013-03-04 19:51:03 -0800988 // add all rpath entries
989 cl::list<std::string>::iterator rp;
990 cl::list<std::string>::iterator rpEnd = ArgRuntimePath.end();
991 for (rp = ArgRuntimePath.begin(); rp != rpEnd; ++rp) {
992 pConfig.options().getRpathList().push_back(*rp);
993 }
994
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800995 // --fatal-warnings
Stephen Hines6f757552013-03-04 19:51:03 -0800996 // pConfig.options().setFatalWarnings(ArgFatalWarnings);
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800997
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800998 // -shared or -pie
999 if (true == ArgShared || true == ArgPIE) {
1000 ArgFileType = mcld::CGFT_DSOFile;
1001 }
1002 else if (true == ArgRelocatable) {
1003 ArgFileType = mcld::CGFT_PARTIAL;
1004 }
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001005 else if (format::Binary == ArgOFormat) {
1006 ArgFileType = mcld::CGFT_BINARY;
1007 }
1008
1009 // -b [input-format], --format=[input-format]
1010 if (format::Binary == ArgFormat)
1011 pConfig.options().setBinaryInput();
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001012
1013 // -V
1014 if (ArgVersion) {
1015 mcld::outs() << "MCLinker - "
1016 << mcld::LinkerConfig::version()
1017 << "\n";
1018 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001019
1020 // set up sysroot
1021 if (!ArgSysRoot.empty()) {
1022 if (exists(ArgSysRoot) && is_directory(ArgSysRoot))
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001023 pConfig.options().setSysroot(ArgSysRoot);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001024 }
1025
1026 // add all search directories
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001027 cl::list<std::string>::iterator sd;
1028 cl::list<std::string>::iterator sdEnd = ArgSearchDirList.end();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001029 for (sd=ArgSearchDirList.begin(); sd!=sdEnd; ++sd) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001030 if (!pConfig.options().directories().insert(*sd)) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001031 // FIXME: need a warning function
1032 errs() << "WARNING: can not open search directory `-L"
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001033 << *sd
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001034 << "'.\n";
1035 }
1036 }
1037
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001038 pConfig.options().setPIE(ArgPIE);
1039 pConfig.options().setTrace(ArgTrace);
1040 pConfig.options().setVerbose(ArgVerbose);
1041 pConfig.options().setMaxErrorNum(ArgMaxErrorNum);
1042 pConfig.options().setMaxWarnNum(ArgMaxWarnNum);
1043 pConfig.options().setEntry(ArgEntry);
1044 pConfig.options().setBsymbolic(ArgBsymbolic);
1045 pConfig.options().setBgroup(ArgBgroup);
1046 pConfig.options().setDyld(ArgDyld);
1047 pConfig.options().setNoUndefined(ArgNoUndefined);
1048 pConfig.options().setMulDefs(ArgAllowMulDefs);
1049 pConfig.options().setEhFrameHdr(ArgEhFrameHdr);
1050 pConfig.options().setNMagic(ArgNMagic);
1051 pConfig.options().setOMagic(ArgOMagic);
Stephen Hines6f757552013-03-04 19:51:03 -08001052 pConfig.options().setStripDebug(ArgStripDebug || ArgStripAll);
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001053 pConfig.options().setExportDynamic(ArgExportDynamic);
1054 pConfig.options().setWarnSharedTextrel(ArgWarnSharedTextrel);
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001055 pConfig.options().setDefineCommon(ArgDefineCommon);
Stephen Hines6f757552013-03-04 19:51:03 -08001056 pConfig.options().setNewDTags(ArgEnableNewDTags);
1057 pConfig.options().setHashStyle(ArgHashStyle);
1058 pConfig.options().setNoStdlib(ArgNoStdlib);
1059
1060 if (ArgStripAll)
1061 pConfig.options().setStripSymbols(mcld::GeneralOptions::StripAllSymbols);
1062 else if (ArgDiscardAll)
1063 pConfig.options().setStripSymbols(mcld::GeneralOptions::StripLocals);
1064 else if (ArgDiscardLocals)
1065 pConfig.options().setStripSymbols(mcld::GeneralOptions::StripTemporaries);
1066 else
1067 pConfig.options().setStripSymbols(mcld::GeneralOptions::KeepAllSymbols);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001068
Zonr Changaffc1502012-07-16 14:28:23 +08001069 // set up rename map, for --wrap
1070 cl::list<std::string>::iterator wname;
1071 cl::list<std::string>::iterator wnameEnd = ArgWrapList.end();
1072 for (wname = ArgWrapList.begin(); wname != wnameEnd; ++wname) {
1073 bool exist = false;
1074
1075 // add wname -> __wrap_wname
1076 mcld::StringEntry<llvm::StringRef>* to_wrap =
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001077 pConfig.scripts().renameMap().insert(*wname, exist);
Zonr Changaffc1502012-07-16 14:28:23 +08001078
1079 std::string to_wrap_str = "__wrap_" + *wname;
1080 to_wrap->setValue(to_wrap_str);
1081
1082 if (exist)
1083 mcld::warning(mcld::diag::rewrap) << *wname << to_wrap_str;
1084
1085 // add __real_wname -> wname
1086 std::string from_real_str = "__real_" + *wname;
1087 mcld::StringEntry<llvm::StringRef>* from_real =
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001088 pConfig.scripts().renameMap().insert(from_real_str, exist);
Zonr Changaffc1502012-07-16 14:28:23 +08001089 from_real->setValue(*wname);
1090 if (exist)
1091 mcld::warning(mcld::diag::rewrap) << *wname << from_real_str;
1092 } // end of for
1093
1094 // set up rename map, for --portable
1095 cl::list<std::string>::iterator pname;
1096 cl::list<std::string>::iterator pnameEnd = ArgPortList.end();
1097 for (pname = ArgPortList.begin(); pname != pnameEnd; ++pname) {
1098 bool exist = false;
1099
1100 // add pname -> pname_portable
1101 mcld::StringEntry<llvm::StringRef>* to_port =
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001102 pConfig.scripts().renameMap().insert(*pname, exist);
Zonr Changaffc1502012-07-16 14:28:23 +08001103
1104 std::string to_port_str = *pname + "_portable";
1105 to_port->setValue(to_port_str);
1106
1107 if (exist)
1108 mcld::warning(mcld::diag::rewrap) << *pname << to_port_str;
1109
1110 // add __real_pname -> pname
1111 std::string from_real_str = "__real_" + *pname;
1112 mcld::StringEntry<llvm::StringRef>* from_real =
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001113 pConfig.scripts().renameMap().insert(from_real_str, exist);
Zonr Changaffc1502012-07-16 14:28:23 +08001114
1115 from_real->setValue(*pname);
1116 if (exist)
1117 mcld::warning(mcld::diag::rewrap) << *pname << from_real_str;
1118 } // end of for
1119
Zonr Changaffc1502012-07-16 14:28:23 +08001120 // add -z options
1121 cl::list<mcld::ZOption>::iterator zOpt;
1122 cl::list<mcld::ZOption>::iterator zOptEnd = ArgZOptionList.end();
1123 for (zOpt = ArgZOptionList.begin(); zOpt != zOptEnd; ++zOpt) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001124 pConfig.options().addZOption(*zOpt);
Zonr Changaffc1502012-07-16 14:28:23 +08001125 }
1126
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001127 if (ArgGCSections) {
1128 mcld::warning(mcld::diag::warn_unsupported_option) << ArgGCSections.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001129 }
1130
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001131 // set up icf mode
1132 switch (ArgICF) {
1133 case icf::None:
1134 break;
1135 case icf::All:
1136 case icf::Safe:
1137 default:
1138 mcld::warning(mcld::diag::warn_unsupported_option) << ArgICF.ArgStr;
1139 break;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001140 }
1141
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001142 if (ArgFIXCA8) {
1143 mcld::warning(mcld::diag::warn_unsupported_option) << ArgFIXCA8.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001144 }
1145
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001146 // add address mappings
1147 // -Ttext
1148 if (-1U != ArgTextSegAddr) {
1149 bool exist = false;
1150 mcld::StringEntry<uint64_t>* text_mapping =
1151 pConfig.scripts().addressMap().insert(".text", exist);
1152 text_mapping->setValue(ArgTextSegAddr);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001153 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001154 // -Tdata
1155 if (-1U != ArgDataSegAddr) {
1156 bool exist = false;
1157 mcld::StringEntry<uint64_t>* data_mapping =
1158 pConfig.scripts().addressMap().insert(".data", exist);
1159 data_mapping->setValue(ArgDataSegAddr);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001160 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001161 // -Tbss
1162 if (-1U != ArgBssSegAddr) {
1163 bool exist = false;
1164 mcld::StringEntry<uint64_t>* bss_mapping =
1165 pConfig.scripts().addressMap().insert(".bss", exist);
1166 bss_mapping->setValue(ArgBssSegAddr);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001167 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001168 // --section-start SECTION=ADDRESS
1169 for (cl::list<std::string>::iterator
1170 it = ArgAddressMapList.begin(), ie = ArgAddressMapList.end();
1171 it != ie; ++it) {
1172 // FIXME: Add a cl::parser
1173 size_t pos = (*it).find_last_of('=');
1174 llvm::StringRef script(*it);
1175 uint64_t address = 0x0;
1176 script.substr(pos + 1).getAsInteger(0, address);
1177 bool exist = false;
1178 mcld::StringEntry<uint64_t>* addr_mapping =
1179 pConfig.scripts().addressMap().insert(script.substr(0, pos), exist);
1180 addr_mapping->setValue(address);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001181 }
1182
Stephen Hines6f757552013-03-04 19:51:03 -08001183 // set up filter/aux filter for shared object
1184 pConfig.options().setFilter(ArgFilter);
1185
1186 cl::list<std::string>::iterator aux;
1187 cl::list<std::string>::iterator auxEnd = ArgAuxiliary.end();
1188 for (aux = ArgAuxiliary.begin(); aux != auxEnd; ++aux)
1189 pConfig.options().getAuxiliaryList().push_back(*aux);
1190
Zonr Changaffc1502012-07-16 14:28:23 +08001191 return true;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001192}
1193
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001194int main(int argc, char* argv[])
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001195{
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001196 LLVMContext &Context = getGlobalContext();
1197 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
Zonr Changaffc1502012-07-16 14:28:23 +08001198
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001199 // Initialize targets first, so that --version shows registered targets.
1200 InitializeAllTargets();
1201 InitializeAllAsmPrinters();
1202 InitializeAllAsmParsers();
1203 InitializeAllTargetMCs();
1204 mcld::InitializeAllTargets();
1205 mcld::InitializeAllLinkers();
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001206 mcld::InitializeAllEmulations();
Zonr Changaffc1502012-07-16 14:28:23 +08001207 mcld::InitializeAllDiagnostics();
1208
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001209 ParseProgName(argv[0]);
1210 cl::ParseCommandLineOptions(argc, argv, "MCLinker\n");
1211
1212#ifdef ENABLE_UNITTEST
1213 if (UnitTest) {
1214 return unit_test( argc, argv );
1215 }
1216#endif
1217
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001218 // Load the module to be compiled...
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001219 std::auto_ptr<llvm::Module> M;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001220
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001221 // Load the module to be linked...
1222 mcld::Module LDIRModule;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001223
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001224 mcld::LinkerConfig LDConfig;
1225
1226 // Process the linker input from the command line
1227 if (!ProcessLinkerOptionsFromCommand(LDConfig)) {
1228 errs() << argv[0] << ": failed to process linker options from command line!\n";
1229 return 1;
Zonr Changaffc1502012-07-16 14:28:23 +08001230 }
1231
1232 if (ArgBitcodeFilename.empty() &&
1233 (mcld::CGFT_DSOFile != ArgFileType &&
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001234 mcld::CGFT_EXEFile != ArgFileType &&
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001235 mcld::CGFT_PARTIAL != ArgFileType &&
1236 mcld::CGFT_BINARY != ArgFileType)) {
Zonr Changaffc1502012-07-16 14:28:23 +08001237 // If the file is not given, forcefully read from stdin
1238 if (ArgVerbose >= 0) {
1239 errs() << "** The bitcode/llvm asm file is not given. Read from stdin.\n"
1240 << "** Specify input bitcode/llvm asm file by\n\n"
1241 << " llvm-mcld -dB [the bitcode/llvm asm]\n\n";
1242 }
1243
1244 ArgBitcodeFilename.assign("-");
1245 }
1246
1247 if (!ArgBitcodeFilename.empty()) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001248 SMDiagnostic Err;
Zonr Changaffc1502012-07-16 14:28:23 +08001249 M.reset(ParseIRFile(ArgBitcodeFilename.native(), Err, Context));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001250
1251 if (M.get() == 0) {
1252 Err.print(argv[0], errs());
1253 errs() << "** Failed to to the given bitcode/llvm asm file '"
Zonr Changaffc1502012-07-16 14:28:23 +08001254 << ArgBitcodeFilename.native() << "'. **\n";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001255 return 1;
1256 }
Zonr Changaffc1502012-07-16 14:28:23 +08001257 }
1258 else {
1259 // If here, output must be dynamic shared object (mcld::CGFT_DSOFile) and
1260 // executable file (mcld::CGFT_EXEFile).
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001261 M.reset(new Module("Empty Module", Context));
1262 }
1263 Module &mod = *M.get();
1264
1265 // If we are supposed to override the target triple, do so now.
1266 Triple TheTriple;
1267 if (!TargetTriple.empty()) {
1268 TheTriple.setTriple(TargetTriple);
1269 mod.setTargetTriple(TargetTriple);
1270 }
1271
1272 // User doesn't specify the triple from command.
1273 if (TheTriple.getTriple().empty()) {
1274 // Try to get one from the input Module.
1275 const std::string &TripleStr = mod.getTargetTriple();
1276
1277 if (TripleStr.empty())
1278 TheTriple.setTriple(sys::getDefaultTargetTriple());
1279 else
1280 TheTriple.setTriple(TripleStr);
1281 }
1282
1283 // Allocate target machine. First, check whether the user has explicitly
1284 // specified an architecture to compile for. If so we have to look it up by
1285 // name, because it might be a backend that has no mapping to a target triple.
1286 const mcld::Target *TheTarget = 0;
1287 if (!MArch.empty()) {
1288 for (mcld::TargetRegistry::iterator it = mcld::TargetRegistry::begin(),
1289 ie = mcld::TargetRegistry::end(); it != ie; ++it) {
1290 if (MArch == (*it)->get()->getName()) {
1291 TheTarget = *it;
1292 break;
1293 }
1294 }
1295
1296 if (!TheTarget) {
1297 errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
1298 return 1;
1299 }
1300
1301 // Adjust the triple to match (if known), otherwise stick with the
1302 // module/host triple.
1303 Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
1304 if (Type != Triple::UnknownArch)
1305 TheTriple.setArch(Type);
1306 }
1307 else {
1308 std::string Err;
1309 TheTarget = mcld::TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
1310 if (TheTarget == 0) {
Zonr Changaffc1502012-07-16 14:28:23 +08001311 errs() << "error: auto-selecting target `" << TheTriple.getTriple()
1312 << "'\n"
1313 << "Please use the -march option to explicitly select a target.\n"
1314 << "Example:\n"
1315 << " $ " << argv[0] << " -march=arm\n";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001316 return 1;
1317 }
1318 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001319 // Set up mcld::LinkerConfig
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001320 LDConfig.targets().setTriple(TheTriple);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001321
1322 // Package up features to be passed to target/subtarget
1323 std::string FeaturesStr;
1324 if (MAttrs.size()) {
1325 SubtargetFeatures Features;
1326 for (unsigned i = 0; i != MAttrs.size(); ++i)
1327 Features.AddFeature(MAttrs[i]);
1328 FeaturesStr = Features.getString();
1329 }
1330
1331 CodeGenOpt::Level OLvl = CodeGenOpt::Default;
1332 switch (OptLevel) {
1333 default:
1334 errs() << argv[0] << ": invalid optimization level.\n";
1335 return 1;
1336 case ' ': break;
1337 case '0': OLvl = CodeGenOpt::None; break;
1338 case '1': OLvl = CodeGenOpt::Less; break;
1339 case '2': OLvl = CodeGenOpt::Default; break;
1340 case '3': OLvl = CodeGenOpt::Aggressive; break;
1341 }
1342
Zonr Changaffc1502012-07-16 14:28:23 +08001343 // set -fPIC
1344 if (ArgFPIC)
1345 ArgRelocModel = Reloc::PIC_;
1346
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001347 TargetOptions Options;
1348 Options.LessPreciseFPMADOption = EnableFPMAD;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001349 Options.NoFramePointerElim = DisableFPElim;
1350 Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf;
Shih-wei Liaocedee4b2012-08-02 23:13:03 -07001351 Options.AllowFPOpFusion = FuseFPOps;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001352 Options.UnsafeFPMath = EnableUnsafeFPMath;
1353 Options.NoInfsFPMath = EnableNoInfsFPMath;
1354 Options.NoNaNsFPMath = EnableNoNaNsFPMath;
1355 Options.HonorSignDependentRoundingFPMathOption =
1356 EnableHonorSignDependentRoundingFPMath;
1357 Options.UseSoftFloat = GenerateSoftFloatCalls;
1358 if (FloatABIForCalls != FloatABI::Default)
1359 Options.FloatABIType = FloatABIForCalls;
1360 Options.NoZerosInBSS = DontPlaceZerosInBSS;
1361 Options.JITExceptionHandling = EnableJITExceptionHandling;
1362 Options.JITEmitDebugInfo = EmitJitDebugInfo;
1363 Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk;
1364 Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
1365 Options.StackAlignmentOverride = OverrideStackAlignment;
1366 Options.RealignStack = EnableRealignStack;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001367 Options.TrapFuncName = TrapFuncName;
1368 Options.EnableSegmentedStacks = SegmentedStacks;
1369
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001370 std::auto_ptr<mcld::MCLDTargetMachine> target_machine(
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001371 TheTarget->createTargetMachine(TheTriple.getTriple(),
1372 MCPU, FeaturesStr, Options,
Zonr Changaffc1502012-07-16 14:28:23 +08001373 ArgRelocModel, CMModel, OLvl));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001374 assert(target_machine.get() && "Could not allocate target machine!");
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001375 mcld::MCLDTargetMachine &TheTargetMachine = *target_machine.get();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001376
1377 TheTargetMachine.getTM().setMCUseLoc(false);
1378 TheTargetMachine.getTM().setMCUseCFI(false);
1379
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001380 // FIXME: Move the initialization of LineInfo to mcld::Linker when we
1381 // finish LineInfo's implementation.
Zonr Changaffc1502012-07-16 14:28:23 +08001382 OwningPtr<mcld::DiagnosticLineInfo>
Shih-wei Liao67e37f12012-07-27 03:50:34 -07001383 diag_line_info(TheTarget->createDiagnosticLineInfo(*TheTarget,
Zonr Changaffc1502012-07-16 14:28:23 +08001384 TheTriple.getTriple()));
Zonr Changaffc1502012-07-16 14:28:23 +08001385
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001386 mcld::getDiagnosticEngine().setLineInfo(*diag_line_info.take());
Zonr Changaffc1502012-07-16 14:28:23 +08001387
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001388 // Figure out where we are going to send the output...
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001389 OwningPtr<mcld::ToolOutputFile>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001390 Out(GetOutputStream(TheTarget->get()->getName(),
1391 TheTriple.getOS(),
Zonr Changaffc1502012-07-16 14:28:23 +08001392 ArgFileType,
1393 ArgBitcodeFilename,
1394 ArgOutputFilename));
1395 if (!Out) {
1396 // FIXME: show some error message pls.
1397 return 1;
1398 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001399
1400 // Build up all of the passes that we want to do to the module.
1401 PassManager PM;
1402
Shih-wei Liao86036a32013-01-14 19:16:03 -08001403 // Add the data layout from the target machine, if it exists, or the module.
1404 if (const DataLayout *DL = TheTargetMachine.getTM().getDataLayout())
1405 PM.add(new DataLayout(*DL));
1406 else
1407 PM.add(new DataLayout(&mod));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001408
1409 // Override default to generate verbose assembly.
1410 TheTargetMachine.getTM().setAsmVerbosityDefault(true);
1411
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001412 {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001413 // Ask the target to add backend passes as necessary.
1414 if( TheTargetMachine.addPassesToEmitFile(PM,
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001415 *Out,
Zonr Changaffc1502012-07-16 14:28:23 +08001416 ArgFileType,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001417 OLvl,
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001418 LDIRModule,
1419 LDConfig,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001420 NoVerify)) {
1421 errs() << argv[0] << ": target does not support generation of this"
1422 << " file type!\n";
1423 return 1;
1424 }
1425
1426 // Before executing passes, print the final values of the LLVM options.
1427 cl::PrintOptionValues();
1428
1429 PM.run(mod);
1430 }
1431
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001432 if (mcld::getDiagnosticEngine().getPrinter()->getNumErrors())
1433 return 1;
1434
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001435 // Declare success.
1436 Out->keep();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001437 return 0;
1438}
1439