blob: e7a48d07c46d17d04fc74ddef540bba457480adc [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
25#include <llvm/Module.h>
26#include <llvm/PassManager.h>
27#include <llvm/Pass.h>
28#include <llvm/ADT/Triple.h>
29#include <llvm/LLVMContext.h>
30#include <llvm/MC/SubtargetFeature.h>
31#include <llvm/Support/CommandLine.h>
32#include <llvm/Support/Debug.h>
33#include <llvm/Support/FormattedStream.h>
34#include <llvm/Support/Host.h>
35#include <llvm/Support/IRReader.h>
36#include <llvm/Support/ManagedStatic.h>
Zonr Changaffc1502012-07-16 14:28:23 +080037#include <llvm/Support/Signals.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070038#include <llvm/Support/TargetRegistry.h>
39#include <llvm/Support/TargetSelect.h>
Zonr Changaffc1502012-07-16 14:28:23 +080040#include <llvm/Support/Process.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070041#include <llvm/Target/TargetData.h>
42#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
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800464/// @{
465/// @name FIXME: begin of unsupported options
466/// @}
467static cl::opt<bool>
468ArgGCSections("gc-sections",
469 cl::desc("Enable garbage collection of unused input sections."),
470 cl::init(false));
471
472static cl::opt<bool>
473ArgNoGCSections("no-gc-sections",
474 cl::desc("disable garbage collection of unused input sections."),
475 cl::init(false));
476
477namespace icf {
478enum Mode {
479 None,
480 All,
481 Safe
482};
483} // namespace of icf
484
485static cl::opt<icf::Mode>
486ArgICF("icf",
487 cl::desc("Identical Code Folding"),
488 cl::init(icf::None),
489 cl::values(
490 clEnumValN(icf::None, "none",
491 "do not perform cold folding"),
492 clEnumValN(icf::All, "all",
493 "always preform cold folding"),
494 clEnumValN(icf::Safe, "safe",
495 "Folds ctors, dtors and functions whose pointers are definitely not taken."),
496 clEnumValEnd));
497
498// FIXME: add this to target options?
499static cl::opt<bool>
500ArgFIXCA8("fix-cortex-a8",
501 cl::desc("Enable Cortex-A8 Thumb-2 branch erratum fix"),
502 cl::init(false));
503
504static cl::opt<bool>
505ArgDiscardLocals("discard-locals",
506 cl::desc("Delete all temporary local symbols."),
507 cl::init(false));
508
509static cl::alias
510ArgDiscardLocalsAlias("X",
511 cl::desc("alias for --discard-locals"),
512 cl::aliasopt(ArgDiscardLocals));
513
514static cl::opt<bool>
515ArgDiscardAll("discard-all",
516 cl::desc("Delete all local symbols."),
517 cl::init(false));
518
519static cl::alias
520ArgDiscardAllAlias("x",
521 cl::desc("alias for --discard-all"),
522 cl::aliasopt(ArgDiscardAll));
523
524static cl::opt<bool>
525ArgNMagic("nmagic",
526 cl::desc("Do not page align data"),
527 cl::init(false));
528
529static cl::alias
530ArgNMagicAlias("n",
531 cl::desc("alias for --nmagic"),
532 cl::aliasopt(ArgNMagic));
533
534static cl::opt<bool>
535ArgOMagic("omagic",
536 cl::desc("Do not page align data, do not make text readonly"),
537 cl::init(false));
538
539static cl::alias
540ArgOMagicAlias("N",
541 cl::desc("alias for --omagic"),
542 cl::aliasopt(ArgOMagic));
543
544static cl::opt<bool>
545ArgStripDebug("strip-debug",
546 cl::desc("Omit debugger symbol information from the output file."),
547 cl::init(false));
548
549static cl::alias
550ArgStripDebugAlias("S",
551 cl::desc("alias for --strip-debug"),
552 cl::aliasopt(ArgStripDebug));
553
554static cl::opt<bool>
555ArgExportDynamic("export-dynamic",
556 cl::desc("Export all dynamic symbols"),
557 cl::init(false));
558
559static cl::alias
560ArgExportDynamicAlias("E",
561 cl::desc("alias for --export-dynamic"),
562 cl::aliasopt(ArgExportDynamic));
563
564static cl::opt<std::string>
565ArgEmulation("m",
566 cl::desc("Set GNU linker emulation"),
567 cl::value_desc("emulation"));
568
569static cl::opt<std::string>
570ArgRuntimePath("rpath",
571 cl::desc("Add a directory to the runtime library search path"),
572 cl::value_desc("dir"));
573
574static cl::opt<std::string>
575ArgRuntimePathLink("rpath-link",
576 cl::desc("Add a directory to the link time library search path"),
577 cl::value_desc("dir"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700578
579static cl::list<std::string>
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800580ArgExcludeLIBS("exclude-libs",
581 cl::CommaSeparated,
582 cl::desc("Exclude libraries from automatic export"),
583 cl::value_desc("lib1,lib2,..."));
584
585static cl::opt<std::string>
586ArgBuildID("build-id",
587 cl::desc("Request creation of \".note.gnu.build-id\" ELF note section."),
588 cl::value_desc("style"));
589
590static cl::opt<std::string>
591ArgForceUndefined("u",
592 cl::desc("Force symbol to be undefined in the output file"),
593 cl::value_desc("symbol"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700594
595static cl::alias
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800596ArgForceUndefinedAlias("undefined",
597 cl::desc("alias for -u"),
598 cl::aliasopt(ArgForceUndefined));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700599
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800600static cl::opt<std::string>
601ArgVersionScript("version-script",
602 cl::desc("Version script."),
603 cl::value_desc("Version script"));
604
605static cl::opt<bool>
606ArgNoStdLib("nostdlib",
607 cl::desc("Only search lib dirs explicitly specified on cmdline"),
608 cl::init(false));
609
610static cl::opt<bool>
611ArgWarnCommon("warn-common",
612 cl::desc("warn common symbol"),
613 cl::init(false));
614
615static cl::opt<bool>
616ArgFatalWarnings("fatal-warnings",
617 cl::desc("turn all warnings into errors"),
618 cl::init(false));
619
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800620/// @{
621/// @name FIXME: end of unsupported options
622/// @}
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700623
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800624static cl::opt<bool>
625ArgWarnSharedTextrel("warn-shared-textrel",
626 cl::desc("Warn if adding DT_TEXTREL in a shared object."),
627 cl::init(false));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700628
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800629namespace format {
630enum Format {
631 Binary,
632 Unknown // decided by triple
633};
634} // namespace of format
635
636static cl::opt<format::Format>
637ArgFormat("b",
638 cl::value_desc("Format"),
639 cl::desc("set input format"),
640 cl::init(format::Unknown),
641 cl::values(
642 clEnumValN(format::Binary, "binary",
643 "read in binary machine code."),
644 clEnumValEnd));
645
646static cl::alias
647ArgFormatAlias("format",
648 cl::desc("alias for -b"),
649 cl::aliasopt(ArgFormat));
650
651static cl::opt<format::Format>
652ArgOFormat("oformat",
653 cl::value_desc("Format"),
654 cl::desc("set output format"),
655 cl::init(format::Unknown),
656 cl::values(
657 clEnumValN(format::Binary, "binary",
658 "generate binary machine code."),
659 clEnumValEnd));
660
661static cl::opt<bool>
662ArgDefineCommon("d",
663 cl::ZeroOrMore,
664 cl::desc("Define common symbol"),
665 cl::init(false));
666
667static cl::alias
668ArgDefineCommonAlias1("dc",
669 cl::desc("alias for -d"),
670 cl::aliasopt(ArgDefineCommon));
671
672static cl::alias
673ArgDefineCommonAlias2("dp",
674 cl::desc("alias for -d"),
675 cl::aliasopt(ArgDefineCommon));
676
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700677//===----------------------------------------------------------------------===//
678// Scripting Options
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800679//===----------------------------------------------------------------------===//
Zonr Changaffc1502012-07-16 14:28:23 +0800680static cl::list<std::string>
681ArgWrapList("wrap",
682 cl::ZeroOrMore,
683 cl::desc("Use a wrap function fo symbol."),
684 cl::value_desc("symbol"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700685
Zonr Changaffc1502012-07-16 14:28:23 +0800686static cl::list<std::string>
687ArgPortList("portable",
688 cl::ZeroOrMore,
689 cl::desc("Use a portable function fo symbol."),
690 cl::value_desc("symbol"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700691
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800692static cl::list<std::string>
693ArgAddressMapList("section-start",
694 cl::ZeroOrMore,
695 cl::desc("Locate a output section at the given absolute address"),
696 cl::value_desc("Set address of section"),
697 cl::Prefix);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700698
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800699static cl::opt<unsigned long long>
700ArgBssSegAddr("Tbss",
701 cl::desc("Set the address of the bss segment"),
702 cl::init(-1U));
703
704static cl::opt<unsigned long long>
705ArgDataSegAddr("Tdata",
706 cl::desc("Set the address of the data segment"),
707 cl::init(-1U));
708
709static cl::opt<unsigned long long>
710ArgTextSegAddr("Ttext",
711 cl::desc("Set the address of the text segment"),
712 cl::init(-1U));
713
714//===----------------------------------------------------------------------===//
715// non-member functions
716//===----------------------------------------------------------------------===//
Zonr Changaffc1502012-07-16 14:28:23 +0800717/// GetOutputStream - get the output stream.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800718static mcld::ToolOutputFile *GetOutputStream(const char* pTargetName,
719 Triple::OSType pOSType,
720 mcld::CodeGenFileType pFileType,
721 const mcld::sys::fs::Path& pInputFilename,
722 mcld::sys::fs::Path& pOutputFilename)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700723{
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700724 if (pOutputFilename.empty()) {
Zonr Changaffc1502012-07-16 14:28:23 +0800725 if (0 == pInputFilename.native().compare("-"))
726 pOutputFilename.assign("-");
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700727 else {
Zonr Changaffc1502012-07-16 14:28:23 +0800728 switch(pFileType) {
729 case mcld::CGFT_ASMFile: {
730 if (0 == pInputFilename.native().compare("-"))
731 pOutputFilename.assign("_out");
732 else
733 pOutputFilename.assign(pInputFilename.stem().native());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700734
Zonr Changaffc1502012-07-16 14:28:23 +0800735 if (0 == strcmp(pTargetName, "c"))
736 pOutputFilename.native() += ".cbe.c";
737 else if (0 == strcmp(pTargetName, "cpp"))
738 pOutputFilename.native() += ".cpp";
739 else
740 pOutputFilename.native() += ".s";
741 }
742 break;
743
744 case mcld::CGFT_OBJFile: {
745 if (0 == pInputFilename.native().compare("-"))
746 pOutputFilename.assign("_out");
747 else
748 pOutputFilename.assign(pInputFilename.stem().native());
749
750 if (pOSType == Triple::Win32)
751 pOutputFilename.native() += ".obj";
752 else
753 pOutputFilename.native() += ".o";
754 }
755 break;
756
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800757 case mcld::CGFT_PARTIAL: {
758 if (Triple::Win32 == pOSType) {
759 if (0 == pInputFilename.native().compare("-"))
760 pOutputFilename.assign("_out");
761 else
762 pOutputFilename.assign(pInputFilename.stem().native());
763 pOutputFilename.native() += ".obj";
764 }
765 else
766 pOutputFilename.assign("a.out");
767 }
768 break;
769
Zonr Changaffc1502012-07-16 14:28:23 +0800770 case mcld::CGFT_DSOFile: {
771 if (Triple::Win32 == pOSType) {
772 if (0 == pInputFilename.native().compare("-"))
773 pOutputFilename.assign("_out");
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700774 else
Zonr Changaffc1502012-07-16 14:28:23 +0800775 pOutputFilename.assign(pInputFilename.stem().native());
776 pOutputFilename.native() += ".dll";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700777 }
778 else
Zonr Changaffc1502012-07-16 14:28:23 +0800779 pOutputFilename.assign("a.out");
780 }
781 break;
782
783 case mcld::CGFT_EXEFile: {
784 if (Triple::Win32 == pOSType) {
785 if (0 == pInputFilename.native().compare("-"))
786 pOutputFilename.assign("_out");
787 else
788 pOutputFilename.assign(pInputFilename.stem().native());
789 pOutputFilename.native() += ".exe";
790 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700791 else
Zonr Changaffc1502012-07-16 14:28:23 +0800792 pOutputFilename.assign("a.out");
793 }
794 break;
795
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700796 case mcld::CGFT_NULLFile:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700797 break;
798 default:
Zonr Changaffc1502012-07-16 14:28:23 +0800799 llvm::report_fatal_error("Unknown output file type.\n");
800 } // end of switch
801 } // end of ! pInputFilename == "-"
802 } // end of if empty pOutputFilename
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700803
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800804 mcld::FileHandle::Permission permission;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700805 switch (pFileType) {
806 default: assert(0 && "Unknown file type");
807 case mcld::CGFT_ASMFile:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700808 case mcld::CGFT_OBJFile:
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800809 case mcld::CGFT_PARTIAL:
810 permission = 0644;
811 break;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700812 case mcld::CGFT_DSOFile:
813 case mcld::CGFT_EXEFile:
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800814 case mcld::CGFT_BINARY:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700815 case mcld::CGFT_NULLFile:
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800816 permission = 0755;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700817 break;
818 }
819
820 // Open the file.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800821 mcld::ToolOutputFile* result_output =
822 new mcld::ToolOutputFile(pOutputFilename,
823 mcld::FileHandle::ReadWrite |
824 mcld::FileHandle::Create |
825 mcld::FileHandle::Truncate,
826 permission);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700827
Zonr Changaffc1502012-07-16 14:28:23 +0800828 return result_output;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700829}
830
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800831/// ParseProgName - Parse program name
832/// This function simplifies cross-compiling by reading triple from the program
833/// name. For example, if the program name is `arm-linux-eabi-ld.mcld', we can
834/// get the triple is arm-linux-eabi by the program name.
835static void ParseProgName(const char *progname)
836{
837 static const char *suffixes[] = {
838 "ld",
839 "ld.mcld",
840 };
841
842 std::string ProgName(mcld::sys::fs::Path(progname).stem().native());
843
844 for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
845 if (ProgName == suffixes[i])
846 return;
847 }
848
849 StringRef ProgNameRef(ProgName);
850 StringRef Prefix;
851
852 for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
853 if (!ProgNameRef.endswith(suffixes[i]))
854 continue;
855
856 StringRef::size_type LastComponent = ProgNameRef.rfind('-',
857 ProgNameRef.size() - strlen(suffixes[i]));
858 if (LastComponent == StringRef::npos)
859 continue;
860 StringRef Prefix = ProgNameRef.slice(0, LastComponent);
861 std::string IgnoredError;
862 if (!llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError))
863 continue;
864 TargetTriple = Prefix.str();
865 return;
866 }
867}
868
Zonr Changaffc1502012-07-16 14:28:23 +0800869static bool ShouldColorize()
870{
871 const char* term = getenv("TERM");
872 return term && (0 != strcmp(term, "dumb"));
873}
874
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800875static bool ProcessLinkerOptionsFromCommand(mcld::LinkerConfig& pConfig) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700876 // ----- Set up General Options ----- //
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800877 // set up colorize
878 switch (ArgColor) {
879 case color::Never:
880 pConfig.options().setColor(false);
881 break;
882 case color::Always:
883 pConfig.options().setColor(true);
884 break;
885 case color::Auto:
886 bool color_option = ShouldColorize() &&
887 llvm::sys::Process::FileDescriptorIsDisplayed(STDOUT_FILENO);
888 pConfig.options().setColor(color_option);
889 break;
890 }
891
892 mcld::outs().setColor(pConfig.options().color());
893 mcld::errs().setColor(pConfig.options().color());
894
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700895 // set up soname
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800896 pConfig.options().setSOName(ArgSOName);
897
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800898 // --fatal-warnings
899 pConfig.options().setFatalWarnings(ArgFatalWarnings);
900
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800901 // -shared or -pie
902 if (true == ArgShared || true == ArgPIE) {
903 ArgFileType = mcld::CGFT_DSOFile;
904 }
905 else if (true == ArgRelocatable) {
906 ArgFileType = mcld::CGFT_PARTIAL;
907 }
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800908 else if (format::Binary == ArgOFormat) {
909 ArgFileType = mcld::CGFT_BINARY;
910 }
911
912 // -b [input-format], --format=[input-format]
913 if (format::Binary == ArgFormat)
914 pConfig.options().setBinaryInput();
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800915
916 // -V
917 if (ArgVersion) {
918 mcld::outs() << "MCLinker - "
919 << mcld::LinkerConfig::version()
920 << "\n";
921 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700922
923 // set up sysroot
924 if (!ArgSysRoot.empty()) {
925 if (exists(ArgSysRoot) && is_directory(ArgSysRoot))
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800926 pConfig.options().setSysroot(ArgSysRoot);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700927 }
928
929 // add all search directories
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800930 cl::list<std::string>::iterator sd;
931 cl::list<std::string>::iterator sdEnd = ArgSearchDirList.end();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700932 for (sd=ArgSearchDirList.begin(); sd!=sdEnd; ++sd) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800933 if (!pConfig.options().directories().insert(*sd)) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700934 // FIXME: need a warning function
935 errs() << "WARNING: can not open search directory `-L"
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800936 << *sd
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700937 << "'.\n";
938 }
939 }
940
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800941 pConfig.options().setPIE(ArgPIE);
942 pConfig.options().setTrace(ArgTrace);
943 pConfig.options().setVerbose(ArgVerbose);
944 pConfig.options().setMaxErrorNum(ArgMaxErrorNum);
945 pConfig.options().setMaxWarnNum(ArgMaxWarnNum);
946 pConfig.options().setEntry(ArgEntry);
947 pConfig.options().setBsymbolic(ArgBsymbolic);
948 pConfig.options().setBgroup(ArgBgroup);
949 pConfig.options().setDyld(ArgDyld);
950 pConfig.options().setNoUndefined(ArgNoUndefined);
951 pConfig.options().setMulDefs(ArgAllowMulDefs);
952 pConfig.options().setEhFrameHdr(ArgEhFrameHdr);
953 pConfig.options().setNMagic(ArgNMagic);
954 pConfig.options().setOMagic(ArgOMagic);
955 pConfig.options().setStripDebug(ArgStripDebug);
956 pConfig.options().setExportDynamic(ArgExportDynamic);
957 pConfig.options().setWarnSharedTextrel(ArgWarnSharedTextrel);
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800958 pConfig.options().setDefineCommon(ArgDefineCommon);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700959
Zonr Changaffc1502012-07-16 14:28:23 +0800960 // set up rename map, for --wrap
961 cl::list<std::string>::iterator wname;
962 cl::list<std::string>::iterator wnameEnd = ArgWrapList.end();
963 for (wname = ArgWrapList.begin(); wname != wnameEnd; ++wname) {
964 bool exist = false;
965
966 // add wname -> __wrap_wname
967 mcld::StringEntry<llvm::StringRef>* to_wrap =
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800968 pConfig.scripts().renameMap().insert(*wname, exist);
Zonr Changaffc1502012-07-16 14:28:23 +0800969
970 std::string to_wrap_str = "__wrap_" + *wname;
971 to_wrap->setValue(to_wrap_str);
972
973 if (exist)
974 mcld::warning(mcld::diag::rewrap) << *wname << to_wrap_str;
975
976 // add __real_wname -> wname
977 std::string from_real_str = "__real_" + *wname;
978 mcld::StringEntry<llvm::StringRef>* from_real =
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800979 pConfig.scripts().renameMap().insert(from_real_str, exist);
Zonr Changaffc1502012-07-16 14:28:23 +0800980 from_real->setValue(*wname);
981 if (exist)
982 mcld::warning(mcld::diag::rewrap) << *wname << from_real_str;
983 } // end of for
984
985 // set up rename map, for --portable
986 cl::list<std::string>::iterator pname;
987 cl::list<std::string>::iterator pnameEnd = ArgPortList.end();
988 for (pname = ArgPortList.begin(); pname != pnameEnd; ++pname) {
989 bool exist = false;
990
991 // add pname -> pname_portable
992 mcld::StringEntry<llvm::StringRef>* to_port =
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800993 pConfig.scripts().renameMap().insert(*pname, exist);
Zonr Changaffc1502012-07-16 14:28:23 +0800994
995 std::string to_port_str = *pname + "_portable";
996 to_port->setValue(to_port_str);
997
998 if (exist)
999 mcld::warning(mcld::diag::rewrap) << *pname << to_port_str;
1000
1001 // add __real_pname -> pname
1002 std::string from_real_str = "__real_" + *pname;
1003 mcld::StringEntry<llvm::StringRef>* from_real =
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001004 pConfig.scripts().renameMap().insert(from_real_str, exist);
Zonr Changaffc1502012-07-16 14:28:23 +08001005
1006 from_real->setValue(*pname);
1007 if (exist)
1008 mcld::warning(mcld::diag::rewrap) << *pname << from_real_str;
1009 } // end of for
1010
Zonr Changaffc1502012-07-16 14:28:23 +08001011 // add -z options
1012 cl::list<mcld::ZOption>::iterator zOpt;
1013 cl::list<mcld::ZOption>::iterator zOptEnd = ArgZOptionList.end();
1014 for (zOpt = ArgZOptionList.begin(); zOpt != zOptEnd; ++zOpt) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001015 pConfig.options().addZOption(*zOpt);
Zonr Changaffc1502012-07-16 14:28:23 +08001016 }
1017
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001018 if (ArgGCSections) {
1019 mcld::warning(mcld::diag::warn_unsupported_option) << ArgGCSections.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001020 }
1021
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001022 // set up icf mode
1023 switch (ArgICF) {
1024 case icf::None:
1025 break;
1026 case icf::All:
1027 case icf::Safe:
1028 default:
1029 mcld::warning(mcld::diag::warn_unsupported_option) << ArgICF.ArgStr;
1030 break;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001031 }
1032
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001033 if (ArgFIXCA8) {
1034 mcld::warning(mcld::diag::warn_unsupported_option) << ArgFIXCA8.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001035 }
1036
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001037 if (ArgDiscardLocals) {
1038 mcld::warning(mcld::diag::warn_unsupported_option) << ArgDiscardLocals.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001039 }
1040
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001041 if (ArgDiscardAll) {
1042 mcld::warning(mcld::diag::warn_unsupported_option) << ArgDiscardAll.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001043 }
1044
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001045 // add address mappings
1046 // -Ttext
1047 if (-1U != ArgTextSegAddr) {
1048 bool exist = false;
1049 mcld::StringEntry<uint64_t>* text_mapping =
1050 pConfig.scripts().addressMap().insert(".text", exist);
1051 text_mapping->setValue(ArgTextSegAddr);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001052 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001053 // -Tdata
1054 if (-1U != ArgDataSegAddr) {
1055 bool exist = false;
1056 mcld::StringEntry<uint64_t>* data_mapping =
1057 pConfig.scripts().addressMap().insert(".data", exist);
1058 data_mapping->setValue(ArgDataSegAddr);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001059 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001060 // -Tbss
1061 if (-1U != ArgBssSegAddr) {
1062 bool exist = false;
1063 mcld::StringEntry<uint64_t>* bss_mapping =
1064 pConfig.scripts().addressMap().insert(".bss", exist);
1065 bss_mapping->setValue(ArgBssSegAddr);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001066 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001067 // --section-start SECTION=ADDRESS
1068 for (cl::list<std::string>::iterator
1069 it = ArgAddressMapList.begin(), ie = ArgAddressMapList.end();
1070 it != ie; ++it) {
1071 // FIXME: Add a cl::parser
1072 size_t pos = (*it).find_last_of('=');
1073 llvm::StringRef script(*it);
1074 uint64_t address = 0x0;
1075 script.substr(pos + 1).getAsInteger(0, address);
1076 bool exist = false;
1077 mcld::StringEntry<uint64_t>* addr_mapping =
1078 pConfig.scripts().addressMap().insert(script.substr(0, pos), exist);
1079 addr_mapping->setValue(address);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001080 }
1081
Zonr Changaffc1502012-07-16 14:28:23 +08001082 return true;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001083}
1084
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001085int main(int argc, char* argv[])
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001086{
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001087 LLVMContext &Context = getGlobalContext();
1088 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
Zonr Changaffc1502012-07-16 14:28:23 +08001089
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001090 // Initialize targets first, so that --version shows registered targets.
1091 InitializeAllTargets();
1092 InitializeAllAsmPrinters();
1093 InitializeAllAsmParsers();
1094 InitializeAllTargetMCs();
1095 mcld::InitializeAllTargets();
1096 mcld::InitializeAllLinkers();
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001097 mcld::InitializeAllEmulations();
Zonr Changaffc1502012-07-16 14:28:23 +08001098 mcld::InitializeAllDiagnostics();
1099
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001100 ParseProgName(argv[0]);
1101 cl::ParseCommandLineOptions(argc, argv, "MCLinker\n");
1102
1103#ifdef ENABLE_UNITTEST
1104 if (UnitTest) {
1105 return unit_test( argc, argv );
1106 }
1107#endif
1108
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001109 // Load the module to be compiled...
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001110 std::auto_ptr<llvm::Module> M;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001111
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001112 // Load the module to be linked...
1113 mcld::Module LDIRModule;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001114
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001115 mcld::LinkerConfig LDConfig;
1116
1117 // Process the linker input from the command line
1118 if (!ProcessLinkerOptionsFromCommand(LDConfig)) {
1119 errs() << argv[0] << ": failed to process linker options from command line!\n";
1120 return 1;
Zonr Changaffc1502012-07-16 14:28:23 +08001121 }
1122
1123 if (ArgBitcodeFilename.empty() &&
1124 (mcld::CGFT_DSOFile != ArgFileType &&
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001125 mcld::CGFT_EXEFile != ArgFileType &&
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001126 mcld::CGFT_PARTIAL != ArgFileType &&
1127 mcld::CGFT_BINARY != ArgFileType)) {
Zonr Changaffc1502012-07-16 14:28:23 +08001128 // If the file is not given, forcefully read from stdin
1129 if (ArgVerbose >= 0) {
1130 errs() << "** The bitcode/llvm asm file is not given. Read from stdin.\n"
1131 << "** Specify input bitcode/llvm asm file by\n\n"
1132 << " llvm-mcld -dB [the bitcode/llvm asm]\n\n";
1133 }
1134
1135 ArgBitcodeFilename.assign("-");
1136 }
1137
1138 if (!ArgBitcodeFilename.empty()) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001139 SMDiagnostic Err;
Zonr Changaffc1502012-07-16 14:28:23 +08001140 M.reset(ParseIRFile(ArgBitcodeFilename.native(), Err, Context));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001141
1142 if (M.get() == 0) {
1143 Err.print(argv[0], errs());
1144 errs() << "** Failed to to the given bitcode/llvm asm file '"
Zonr Changaffc1502012-07-16 14:28:23 +08001145 << ArgBitcodeFilename.native() << "'. **\n";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001146 return 1;
1147 }
Zonr Changaffc1502012-07-16 14:28:23 +08001148 }
1149 else {
1150 // If here, output must be dynamic shared object (mcld::CGFT_DSOFile) and
1151 // executable file (mcld::CGFT_EXEFile).
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001152 M.reset(new Module("Empty Module", Context));
1153 }
1154 Module &mod = *M.get();
1155
1156 // If we are supposed to override the target triple, do so now.
1157 Triple TheTriple;
1158 if (!TargetTriple.empty()) {
1159 TheTriple.setTriple(TargetTriple);
1160 mod.setTargetTriple(TargetTriple);
1161 }
1162
1163 // User doesn't specify the triple from command.
1164 if (TheTriple.getTriple().empty()) {
1165 // Try to get one from the input Module.
1166 const std::string &TripleStr = mod.getTargetTriple();
1167
1168 if (TripleStr.empty())
1169 TheTriple.setTriple(sys::getDefaultTargetTriple());
1170 else
1171 TheTriple.setTriple(TripleStr);
1172 }
1173
1174 // Allocate target machine. First, check whether the user has explicitly
1175 // specified an architecture to compile for. If so we have to look it up by
1176 // name, because it might be a backend that has no mapping to a target triple.
1177 const mcld::Target *TheTarget = 0;
1178 if (!MArch.empty()) {
1179 for (mcld::TargetRegistry::iterator it = mcld::TargetRegistry::begin(),
1180 ie = mcld::TargetRegistry::end(); it != ie; ++it) {
1181 if (MArch == (*it)->get()->getName()) {
1182 TheTarget = *it;
1183 break;
1184 }
1185 }
1186
1187 if (!TheTarget) {
1188 errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
1189 return 1;
1190 }
1191
1192 // Adjust the triple to match (if known), otherwise stick with the
1193 // module/host triple.
1194 Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
1195 if (Type != Triple::UnknownArch)
1196 TheTriple.setArch(Type);
1197 }
1198 else {
1199 std::string Err;
1200 TheTarget = mcld::TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
1201 if (TheTarget == 0) {
Zonr Changaffc1502012-07-16 14:28:23 +08001202 errs() << "error: auto-selecting target `" << TheTriple.getTriple()
1203 << "'\n"
1204 << "Please use the -march option to explicitly select a target.\n"
1205 << "Example:\n"
1206 << " $ " << argv[0] << " -march=arm\n";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001207 return 1;
1208 }
1209 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001210 // Set up mcld::LinkerConfig
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001211 LDConfig.targets().setTriple(TheTriple);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001212
1213 // Package up features to be passed to target/subtarget
1214 std::string FeaturesStr;
1215 if (MAttrs.size()) {
1216 SubtargetFeatures Features;
1217 for (unsigned i = 0; i != MAttrs.size(); ++i)
1218 Features.AddFeature(MAttrs[i]);
1219 FeaturesStr = Features.getString();
1220 }
1221
1222 CodeGenOpt::Level OLvl = CodeGenOpt::Default;
1223 switch (OptLevel) {
1224 default:
1225 errs() << argv[0] << ": invalid optimization level.\n";
1226 return 1;
1227 case ' ': break;
1228 case '0': OLvl = CodeGenOpt::None; break;
1229 case '1': OLvl = CodeGenOpt::Less; break;
1230 case '2': OLvl = CodeGenOpt::Default; break;
1231 case '3': OLvl = CodeGenOpt::Aggressive; break;
1232 }
1233
Zonr Changaffc1502012-07-16 14:28:23 +08001234 // set -fPIC
1235 if (ArgFPIC)
1236 ArgRelocModel = Reloc::PIC_;
1237
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001238 TargetOptions Options;
1239 Options.LessPreciseFPMADOption = EnableFPMAD;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001240 Options.NoFramePointerElim = DisableFPElim;
1241 Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf;
Shih-wei Liaocedee4b2012-08-02 23:13:03 -07001242 Options.AllowFPOpFusion = FuseFPOps;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001243 Options.UnsafeFPMath = EnableUnsafeFPMath;
1244 Options.NoInfsFPMath = EnableNoInfsFPMath;
1245 Options.NoNaNsFPMath = EnableNoNaNsFPMath;
1246 Options.HonorSignDependentRoundingFPMathOption =
1247 EnableHonorSignDependentRoundingFPMath;
1248 Options.UseSoftFloat = GenerateSoftFloatCalls;
1249 if (FloatABIForCalls != FloatABI::Default)
1250 Options.FloatABIType = FloatABIForCalls;
1251 Options.NoZerosInBSS = DontPlaceZerosInBSS;
1252 Options.JITExceptionHandling = EnableJITExceptionHandling;
1253 Options.JITEmitDebugInfo = EmitJitDebugInfo;
1254 Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk;
1255 Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
1256 Options.StackAlignmentOverride = OverrideStackAlignment;
1257 Options.RealignStack = EnableRealignStack;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001258 Options.TrapFuncName = TrapFuncName;
1259 Options.EnableSegmentedStacks = SegmentedStacks;
1260
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001261 std::auto_ptr<mcld::MCLDTargetMachine> target_machine(
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001262 TheTarget->createTargetMachine(TheTriple.getTriple(),
1263 MCPU, FeaturesStr, Options,
Zonr Changaffc1502012-07-16 14:28:23 +08001264 ArgRelocModel, CMModel, OLvl));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001265 assert(target_machine.get() && "Could not allocate target machine!");
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001266 mcld::MCLDTargetMachine &TheTargetMachine = *target_machine.get();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001267
1268 TheTargetMachine.getTM().setMCUseLoc(false);
1269 TheTargetMachine.getTM().setMCUseCFI(false);
1270
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001271 // FIXME: Move the initialization of LineInfo to mcld::Linker when we
1272 // finish LineInfo's implementation.
Zonr Changaffc1502012-07-16 14:28:23 +08001273 OwningPtr<mcld::DiagnosticLineInfo>
Shih-wei Liao67e37f12012-07-27 03:50:34 -07001274 diag_line_info(TheTarget->createDiagnosticLineInfo(*TheTarget,
Zonr Changaffc1502012-07-16 14:28:23 +08001275 TheTriple.getTriple()));
Zonr Changaffc1502012-07-16 14:28:23 +08001276
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001277 mcld::getDiagnosticEngine().setLineInfo(*diag_line_info.take());
Zonr Changaffc1502012-07-16 14:28:23 +08001278
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001279 // Figure out where we are going to send the output...
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001280 OwningPtr<mcld::ToolOutputFile>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001281 Out(GetOutputStream(TheTarget->get()->getName(),
1282 TheTriple.getOS(),
Zonr Changaffc1502012-07-16 14:28:23 +08001283 ArgFileType,
1284 ArgBitcodeFilename,
1285 ArgOutputFilename));
1286 if (!Out) {
1287 // FIXME: show some error message pls.
1288 return 1;
1289 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001290
1291 // Build up all of the passes that we want to do to the module.
1292 PassManager PM;
1293
1294 // Add the target data from the target machine, if it exists, or the module.
1295 if (const TargetData *TD = TheTargetMachine.getTM().getTargetData())
1296 PM.add(new TargetData(*TD));
1297 else
1298 PM.add(new TargetData(&mod));
1299
1300 // Override default to generate verbose assembly.
1301 TheTargetMachine.getTM().setAsmVerbosityDefault(true);
1302
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001303 {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001304 // Ask the target to add backend passes as necessary.
1305 if( TheTargetMachine.addPassesToEmitFile(PM,
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001306 *Out,
Zonr Changaffc1502012-07-16 14:28:23 +08001307 ArgFileType,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001308 OLvl,
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001309 LDIRModule,
1310 LDConfig,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001311 NoVerify)) {
1312 errs() << argv[0] << ": target does not support generation of this"
1313 << " file type!\n";
1314 return 1;
1315 }
1316
1317 // Before executing passes, print the final values of the LLVM options.
1318 cl::PrintOptionValues();
1319
1320 PM.run(mod);
1321 }
1322
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -08001323 if (mcld::getDiagnosticEngine().getPrinter()->getNumErrors())
1324 return 1;
1325
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001326 // Declare success.
1327 Out->keep();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001328 return 0;
1329}
1330