blob: 28a18c6ea7db892221024c317af2754550f3055f [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 Liao22add6f2012-12-15 17:21:00 -0800286static cl::list<std::string>
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 Liao22add6f2012-12-15 17:21:00 -0800600/// @{
601/// @name FIXME: end of unsupported options
602/// @}
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700603
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800604static cl::opt<bool>
605ArgWarnSharedTextrel("warn-shared-textrel",
606 cl::desc("Warn if adding DT_TEXTREL in a shared object."),
607 cl::init(false));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700608
609//===----------------------------------------------------------------------===//
610// Scripting Options
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800611//===----------------------------------------------------------------------===//
Zonr Changaffc1502012-07-16 14:28:23 +0800612static cl::list<std::string>
613ArgWrapList("wrap",
614 cl::ZeroOrMore,
615 cl::desc("Use a wrap function fo symbol."),
616 cl::value_desc("symbol"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700617
Zonr Changaffc1502012-07-16 14:28:23 +0800618static cl::list<std::string>
619ArgPortList("portable",
620 cl::ZeroOrMore,
621 cl::desc("Use a portable function fo symbol."),
622 cl::value_desc("symbol"));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700623
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800624static cl::list<std::string>
625ArgAddressMapList("section-start",
626 cl::ZeroOrMore,
627 cl::desc("Locate a output section at the given absolute address"),
628 cl::value_desc("Set address of section"),
629 cl::Prefix);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700630
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800631static cl::opt<unsigned long long>
632ArgBssSegAddr("Tbss",
633 cl::desc("Set the address of the bss segment"),
634 cl::init(-1U));
635
636static cl::opt<unsigned long long>
637ArgDataSegAddr("Tdata",
638 cl::desc("Set the address of the data segment"),
639 cl::init(-1U));
640
641static cl::opt<unsigned long long>
642ArgTextSegAddr("Ttext",
643 cl::desc("Set the address of the text segment"),
644 cl::init(-1U));
645
646//===----------------------------------------------------------------------===//
647// non-member functions
648//===----------------------------------------------------------------------===//
Zonr Changaffc1502012-07-16 14:28:23 +0800649/// GetOutputStream - get the output stream.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800650static mcld::ToolOutputFile *GetOutputStream(const char* pTargetName,
651 Triple::OSType pOSType,
652 mcld::CodeGenFileType pFileType,
653 const mcld::sys::fs::Path& pInputFilename,
654 mcld::sys::fs::Path& pOutputFilename)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700655{
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700656 if (pOutputFilename.empty()) {
Zonr Changaffc1502012-07-16 14:28:23 +0800657 if (0 == pInputFilename.native().compare("-"))
658 pOutputFilename.assign("-");
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700659 else {
Zonr Changaffc1502012-07-16 14:28:23 +0800660 switch(pFileType) {
661 case mcld::CGFT_ASMFile: {
662 if (0 == pInputFilename.native().compare("-"))
663 pOutputFilename.assign("_out");
664 else
665 pOutputFilename.assign(pInputFilename.stem().native());
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700666
Zonr Changaffc1502012-07-16 14:28:23 +0800667 if (0 == strcmp(pTargetName, "c"))
668 pOutputFilename.native() += ".cbe.c";
669 else if (0 == strcmp(pTargetName, "cpp"))
670 pOutputFilename.native() += ".cpp";
671 else
672 pOutputFilename.native() += ".s";
673 }
674 break;
675
676 case mcld::CGFT_OBJFile: {
677 if (0 == pInputFilename.native().compare("-"))
678 pOutputFilename.assign("_out");
679 else
680 pOutputFilename.assign(pInputFilename.stem().native());
681
682 if (pOSType == Triple::Win32)
683 pOutputFilename.native() += ".obj";
684 else
685 pOutputFilename.native() += ".o";
686 }
687 break;
688
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800689 case mcld::CGFT_PARTIAL: {
690 if (Triple::Win32 == pOSType) {
691 if (0 == pInputFilename.native().compare("-"))
692 pOutputFilename.assign("_out");
693 else
694 pOutputFilename.assign(pInputFilename.stem().native());
695 pOutputFilename.native() += ".obj";
696 }
697 else
698 pOutputFilename.assign("a.out");
699 }
700 break;
701
Zonr Changaffc1502012-07-16 14:28:23 +0800702 case mcld::CGFT_DSOFile: {
703 if (Triple::Win32 == pOSType) {
704 if (0 == pInputFilename.native().compare("-"))
705 pOutputFilename.assign("_out");
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700706 else
Zonr Changaffc1502012-07-16 14:28:23 +0800707 pOutputFilename.assign(pInputFilename.stem().native());
708 pOutputFilename.native() += ".dll";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700709 }
710 else
Zonr Changaffc1502012-07-16 14:28:23 +0800711 pOutputFilename.assign("a.out");
712 }
713 break;
714
715 case mcld::CGFT_EXEFile: {
716 if (Triple::Win32 == pOSType) {
717 if (0 == pInputFilename.native().compare("-"))
718 pOutputFilename.assign("_out");
719 else
720 pOutputFilename.assign(pInputFilename.stem().native());
721 pOutputFilename.native() += ".exe";
722 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700723 else
Zonr Changaffc1502012-07-16 14:28:23 +0800724 pOutputFilename.assign("a.out");
725 }
726 break;
727
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700728 case mcld::CGFT_NULLFile:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700729 break;
730 default:
Zonr Changaffc1502012-07-16 14:28:23 +0800731 llvm::report_fatal_error("Unknown output file type.\n");
732 } // end of switch
733 } // end of ! pInputFilename == "-"
734 } // end of if empty pOutputFilename
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700735
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800736 mcld::FileHandle::Permission permission;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700737 switch (pFileType) {
738 default: assert(0 && "Unknown file type");
739 case mcld::CGFT_ASMFile:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700740 case mcld::CGFT_OBJFile:
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800741 case mcld::CGFT_PARTIAL:
742 permission = 0644;
743 break;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700744 case mcld::CGFT_DSOFile:
745 case mcld::CGFT_EXEFile:
746 case mcld::CGFT_NULLFile:
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800747 permission = 0755;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700748 break;
749 }
750
751 // Open the file.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800752 mcld::ToolOutputFile* result_output =
753 new mcld::ToolOutputFile(pOutputFilename,
754 mcld::FileHandle::ReadWrite |
755 mcld::FileHandle::Create |
756 mcld::FileHandle::Truncate,
757 permission);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700758
Zonr Changaffc1502012-07-16 14:28:23 +0800759 return result_output;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700760}
761
Zonr Changaffc1502012-07-16 14:28:23 +0800762static bool ShouldColorize()
763{
764 const char* term = getenv("TERM");
765 return term && (0 != strcmp(term, "dumb"));
766}
767
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800768static bool ProcessLinkerOptionsFromCommand(mcld::LinkerConfig& pConfig) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700769 // ----- Set up General Options ----- //
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800770 // set up colorize
771 switch (ArgColor) {
772 case color::Never:
773 pConfig.options().setColor(false);
774 break;
775 case color::Always:
776 pConfig.options().setColor(true);
777 break;
778 case color::Auto:
779 bool color_option = ShouldColorize() &&
780 llvm::sys::Process::FileDescriptorIsDisplayed(STDOUT_FILENO);
781 pConfig.options().setColor(color_option);
782 break;
783 }
784
785 mcld::outs().setColor(pConfig.options().color());
786 mcld::errs().setColor(pConfig.options().color());
787
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700788 // set up soname
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800789 pConfig.options().setSOName(ArgSOName);
790
791 // -shared or -pie
792 if (true == ArgShared || true == ArgPIE) {
793 ArgFileType = mcld::CGFT_DSOFile;
794 }
795 else if (true == ArgRelocatable) {
796 ArgFileType = mcld::CGFT_PARTIAL;
797 }
798
799 // -V
800 if (ArgVersion) {
801 mcld::outs() << "MCLinker - "
802 << mcld::LinkerConfig::version()
803 << "\n";
804 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700805
806 // set up sysroot
807 if (!ArgSysRoot.empty()) {
808 if (exists(ArgSysRoot) && is_directory(ArgSysRoot))
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800809 pConfig.options().setSysroot(ArgSysRoot);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700810 }
811
812 // add all search directories
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800813 cl::list<std::string>::iterator sd;
814 cl::list<std::string>::iterator sdEnd = ArgSearchDirList.end();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700815 for (sd=ArgSearchDirList.begin(); sd!=sdEnd; ++sd) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800816 if (!pConfig.options().directories().insert(*sd)) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700817 // FIXME: need a warning function
818 errs() << "WARNING: can not open search directory `-L"
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800819 << *sd
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700820 << "'.\n";
821 }
822 }
823
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800824 pConfig.options().setPIE(ArgPIE);
825 pConfig.options().setTrace(ArgTrace);
826 pConfig.options().setVerbose(ArgVerbose);
827 pConfig.options().setMaxErrorNum(ArgMaxErrorNum);
828 pConfig.options().setMaxWarnNum(ArgMaxWarnNum);
829 pConfig.options().setEntry(ArgEntry);
830 pConfig.options().setBsymbolic(ArgBsymbolic);
831 pConfig.options().setBgroup(ArgBgroup);
832 pConfig.options().setDyld(ArgDyld);
833 pConfig.options().setNoUndefined(ArgNoUndefined);
834 pConfig.options().setMulDefs(ArgAllowMulDefs);
835 pConfig.options().setEhFrameHdr(ArgEhFrameHdr);
836 pConfig.options().setNMagic(ArgNMagic);
837 pConfig.options().setOMagic(ArgOMagic);
838 pConfig.options().setStripDebug(ArgStripDebug);
839 pConfig.options().setExportDynamic(ArgExportDynamic);
840 pConfig.options().setWarnSharedTextrel(ArgWarnSharedTextrel);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700841
Zonr Changaffc1502012-07-16 14:28:23 +0800842 // set up rename map, for --wrap
843 cl::list<std::string>::iterator wname;
844 cl::list<std::string>::iterator wnameEnd = ArgWrapList.end();
845 for (wname = ArgWrapList.begin(); wname != wnameEnd; ++wname) {
846 bool exist = false;
847
848 // add wname -> __wrap_wname
849 mcld::StringEntry<llvm::StringRef>* to_wrap =
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800850 pConfig.scripts().renameMap().insert(*wname, exist);
Zonr Changaffc1502012-07-16 14:28:23 +0800851
852 std::string to_wrap_str = "__wrap_" + *wname;
853 to_wrap->setValue(to_wrap_str);
854
855 if (exist)
856 mcld::warning(mcld::diag::rewrap) << *wname << to_wrap_str;
857
858 // add __real_wname -> wname
859 std::string from_real_str = "__real_" + *wname;
860 mcld::StringEntry<llvm::StringRef>* from_real =
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800861 pConfig.scripts().renameMap().insert(from_real_str, exist);
Zonr Changaffc1502012-07-16 14:28:23 +0800862 from_real->setValue(*wname);
863 if (exist)
864 mcld::warning(mcld::diag::rewrap) << *wname << from_real_str;
865 } // end of for
866
867 // set up rename map, for --portable
868 cl::list<std::string>::iterator pname;
869 cl::list<std::string>::iterator pnameEnd = ArgPortList.end();
870 for (pname = ArgPortList.begin(); pname != pnameEnd; ++pname) {
871 bool exist = false;
872
873 // add pname -> pname_portable
874 mcld::StringEntry<llvm::StringRef>* to_port =
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800875 pConfig.scripts().renameMap().insert(*pname, exist);
Zonr Changaffc1502012-07-16 14:28:23 +0800876
877 std::string to_port_str = *pname + "_portable";
878 to_port->setValue(to_port_str);
879
880 if (exist)
881 mcld::warning(mcld::diag::rewrap) << *pname << to_port_str;
882
883 // add __real_pname -> pname
884 std::string from_real_str = "__real_" + *pname;
885 mcld::StringEntry<llvm::StringRef>* from_real =
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800886 pConfig.scripts().renameMap().insert(from_real_str, exist);
Zonr Changaffc1502012-07-16 14:28:23 +0800887
888 from_real->setValue(*pname);
889 if (exist)
890 mcld::warning(mcld::diag::rewrap) << *pname << from_real_str;
891 } // end of for
892
Zonr Changaffc1502012-07-16 14:28:23 +0800893 // add -z options
894 cl::list<mcld::ZOption>::iterator zOpt;
895 cl::list<mcld::ZOption>::iterator zOptEnd = ArgZOptionList.end();
896 for (zOpt = ArgZOptionList.begin(); zOpt != zOptEnd; ++zOpt) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800897 pConfig.options().addZOption(*zOpt);
Zonr Changaffc1502012-07-16 14:28:23 +0800898 }
899
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800900 if (ArgGCSections) {
901 mcld::warning(mcld::diag::warn_unsupported_option) << ArgGCSections.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700902 }
903
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800904 // set up icf mode
905 switch (ArgICF) {
906 case icf::None:
907 break;
908 case icf::All:
909 case icf::Safe:
910 default:
911 mcld::warning(mcld::diag::warn_unsupported_option) << ArgICF.ArgStr;
912 break;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700913 }
914
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800915 if (ArgFIXCA8) {
916 mcld::warning(mcld::diag::warn_unsupported_option) << ArgFIXCA8.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700917 }
918
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800919 if (ArgDiscardLocals) {
920 mcld::warning(mcld::diag::warn_unsupported_option) << ArgDiscardLocals.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700921 }
922
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800923 if (ArgDiscardAll) {
924 mcld::warning(mcld::diag::warn_unsupported_option) << ArgDiscardAll.ArgStr;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700925 }
926
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800927 // add address mappings
928 // -Ttext
929 if (-1U != ArgTextSegAddr) {
930 bool exist = false;
931 mcld::StringEntry<uint64_t>* text_mapping =
932 pConfig.scripts().addressMap().insert(".text", exist);
933 text_mapping->setValue(ArgTextSegAddr);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700934 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800935 // -Tdata
936 if (-1U != ArgDataSegAddr) {
937 bool exist = false;
938 mcld::StringEntry<uint64_t>* data_mapping =
939 pConfig.scripts().addressMap().insert(".data", exist);
940 data_mapping->setValue(ArgDataSegAddr);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700941 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800942 // -Tbss
943 if (-1U != ArgBssSegAddr) {
944 bool exist = false;
945 mcld::StringEntry<uint64_t>* bss_mapping =
946 pConfig.scripts().addressMap().insert(".bss", exist);
947 bss_mapping->setValue(ArgBssSegAddr);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700948 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800949 // --section-start SECTION=ADDRESS
950 for (cl::list<std::string>::iterator
951 it = ArgAddressMapList.begin(), ie = ArgAddressMapList.end();
952 it != ie; ++it) {
953 // FIXME: Add a cl::parser
954 size_t pos = (*it).find_last_of('=');
955 llvm::StringRef script(*it);
956 uint64_t address = 0x0;
957 script.substr(pos + 1).getAsInteger(0, address);
958 bool exist = false;
959 mcld::StringEntry<uint64_t>* addr_mapping =
960 pConfig.scripts().addressMap().insert(script.substr(0, pos), exist);
961 addr_mapping->setValue(address);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700962 }
963
Zonr Changaffc1502012-07-16 14:28:23 +0800964 return true;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700965}
966
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800967int main(int argc, char* argv[])
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700968{
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700969 LLVMContext &Context = getGlobalContext();
970 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
Shih-wei Liao67e37f12012-07-27 03:50:34 -0700971 cl::ParseCommandLineOptions(argc, argv, "MCLinker\n");
972
973#ifdef ENABLE_UNITTEST
974 if (UnitTest) {
975 return unit_test( argc, argv );
976 }
977#endif
Zonr Changaffc1502012-07-16 14:28:23 +0800978
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700979 // Initialize targets first, so that --version shows registered targets.
980 InitializeAllTargets();
981 InitializeAllAsmPrinters();
982 InitializeAllAsmParsers();
983 InitializeAllTargetMCs();
984 mcld::InitializeAllTargets();
985 mcld::InitializeAllLinkers();
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800986 mcld::InitializeAllEmulations();
Zonr Changaffc1502012-07-16 14:28:23 +0800987 mcld::InitializeAllDiagnostics();
988
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700989 // Load the module to be compiled...
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800990 std::auto_ptr<llvm::Module> M;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700991
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800992 // Load the module to be linked...
993 mcld::Module LDIRModule;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700994
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800995 mcld::LinkerConfig LDConfig;
996
997 // Process the linker input from the command line
998 if (!ProcessLinkerOptionsFromCommand(LDConfig)) {
999 errs() << argv[0] << ": failed to process linker options from command line!\n";
1000 return 1;
Zonr Changaffc1502012-07-16 14:28:23 +08001001 }
1002
1003 if (ArgBitcodeFilename.empty() &&
1004 (mcld::CGFT_DSOFile != ArgFileType &&
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001005 mcld::CGFT_EXEFile != ArgFileType &&
1006 mcld::CGFT_PARTIAL != ArgFileType)) {
Zonr Changaffc1502012-07-16 14:28:23 +08001007 // If the file is not given, forcefully read from stdin
1008 if (ArgVerbose >= 0) {
1009 errs() << "** The bitcode/llvm asm file is not given. Read from stdin.\n"
1010 << "** Specify input bitcode/llvm asm file by\n\n"
1011 << " llvm-mcld -dB [the bitcode/llvm asm]\n\n";
1012 }
1013
1014 ArgBitcodeFilename.assign("-");
1015 }
1016
1017 if (!ArgBitcodeFilename.empty()) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001018 SMDiagnostic Err;
Zonr Changaffc1502012-07-16 14:28:23 +08001019 M.reset(ParseIRFile(ArgBitcodeFilename.native(), Err, Context));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001020
1021 if (M.get() == 0) {
1022 Err.print(argv[0], errs());
1023 errs() << "** Failed to to the given bitcode/llvm asm file '"
Zonr Changaffc1502012-07-16 14:28:23 +08001024 << ArgBitcodeFilename.native() << "'. **\n";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001025 return 1;
1026 }
Zonr Changaffc1502012-07-16 14:28:23 +08001027 }
1028 else {
1029 // If here, output must be dynamic shared object (mcld::CGFT_DSOFile) and
1030 // executable file (mcld::CGFT_EXEFile).
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001031 M.reset(new Module("Empty Module", Context));
1032 }
1033 Module &mod = *M.get();
1034
1035 // If we are supposed to override the target triple, do so now.
1036 Triple TheTriple;
1037 if (!TargetTriple.empty()) {
1038 TheTriple.setTriple(TargetTriple);
1039 mod.setTargetTriple(TargetTriple);
1040 }
1041
1042 // User doesn't specify the triple from command.
1043 if (TheTriple.getTriple().empty()) {
1044 // Try to get one from the input Module.
1045 const std::string &TripleStr = mod.getTargetTriple();
1046
1047 if (TripleStr.empty())
1048 TheTriple.setTriple(sys::getDefaultTargetTriple());
1049 else
1050 TheTriple.setTriple(TripleStr);
1051 }
1052
1053 // Allocate target machine. First, check whether the user has explicitly
1054 // specified an architecture to compile for. If so we have to look it up by
1055 // name, because it might be a backend that has no mapping to a target triple.
1056 const mcld::Target *TheTarget = 0;
1057 if (!MArch.empty()) {
1058 for (mcld::TargetRegistry::iterator it = mcld::TargetRegistry::begin(),
1059 ie = mcld::TargetRegistry::end(); it != ie; ++it) {
1060 if (MArch == (*it)->get()->getName()) {
1061 TheTarget = *it;
1062 break;
1063 }
1064 }
1065
1066 if (!TheTarget) {
1067 errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
1068 return 1;
1069 }
1070
1071 // Adjust the triple to match (if known), otherwise stick with the
1072 // module/host triple.
1073 Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
1074 if (Type != Triple::UnknownArch)
1075 TheTriple.setArch(Type);
1076 }
1077 else {
1078 std::string Err;
1079 TheTarget = mcld::TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
1080 if (TheTarget == 0) {
Zonr Changaffc1502012-07-16 14:28:23 +08001081 errs() << "error: auto-selecting target `" << TheTriple.getTriple()
1082 << "'\n"
1083 << "Please use the -march option to explicitly select a target.\n"
1084 << "Example:\n"
1085 << " $ " << argv[0] << " -march=arm\n";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001086 return 1;
1087 }
1088 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001089 // Set up mcld::LinkerConfig
1090 LDConfig.setTriple(TheTriple);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001091
1092 // Package up features to be passed to target/subtarget
1093 std::string FeaturesStr;
1094 if (MAttrs.size()) {
1095 SubtargetFeatures Features;
1096 for (unsigned i = 0; i != MAttrs.size(); ++i)
1097 Features.AddFeature(MAttrs[i]);
1098 FeaturesStr = Features.getString();
1099 }
1100
1101 CodeGenOpt::Level OLvl = CodeGenOpt::Default;
1102 switch (OptLevel) {
1103 default:
1104 errs() << argv[0] << ": invalid optimization level.\n";
1105 return 1;
1106 case ' ': break;
1107 case '0': OLvl = CodeGenOpt::None; break;
1108 case '1': OLvl = CodeGenOpt::Less; break;
1109 case '2': OLvl = CodeGenOpt::Default; break;
1110 case '3': OLvl = CodeGenOpt::Aggressive; break;
1111 }
1112
Zonr Changaffc1502012-07-16 14:28:23 +08001113 // set -fPIC
1114 if (ArgFPIC)
1115 ArgRelocModel = Reloc::PIC_;
1116
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001117 TargetOptions Options;
1118 Options.LessPreciseFPMADOption = EnableFPMAD;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001119 Options.NoFramePointerElim = DisableFPElim;
1120 Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf;
Shih-wei Liaocedee4b2012-08-02 23:13:03 -07001121 Options.AllowFPOpFusion = FuseFPOps;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001122 Options.UnsafeFPMath = EnableUnsafeFPMath;
1123 Options.NoInfsFPMath = EnableNoInfsFPMath;
1124 Options.NoNaNsFPMath = EnableNoNaNsFPMath;
1125 Options.HonorSignDependentRoundingFPMathOption =
1126 EnableHonorSignDependentRoundingFPMath;
1127 Options.UseSoftFloat = GenerateSoftFloatCalls;
1128 if (FloatABIForCalls != FloatABI::Default)
1129 Options.FloatABIType = FloatABIForCalls;
1130 Options.NoZerosInBSS = DontPlaceZerosInBSS;
1131 Options.JITExceptionHandling = EnableJITExceptionHandling;
1132 Options.JITEmitDebugInfo = EmitJitDebugInfo;
1133 Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk;
1134 Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
1135 Options.StackAlignmentOverride = OverrideStackAlignment;
1136 Options.RealignStack = EnableRealignStack;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001137 Options.TrapFuncName = TrapFuncName;
1138 Options.EnableSegmentedStacks = SegmentedStacks;
1139
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001140 std::auto_ptr<mcld::MCLDTargetMachine> target_machine(
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001141 TheTarget->createTargetMachine(TheTriple.getTriple(),
1142 MCPU, FeaturesStr, Options,
Zonr Changaffc1502012-07-16 14:28:23 +08001143 ArgRelocModel, CMModel, OLvl));
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001144 assert(target_machine.get() && "Could not allocate target machine!");
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001145 mcld::MCLDTargetMachine &TheTargetMachine = *target_machine.get();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001146
1147 TheTargetMachine.getTM().setMCUseLoc(false);
1148 TheTargetMachine.getTM().setMCUseCFI(false);
1149
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001150 // FIXME: Move the initialization of LineInfo to mcld::Linker when we
1151 // finish LineInfo's implementation.
Zonr Changaffc1502012-07-16 14:28:23 +08001152 OwningPtr<mcld::DiagnosticLineInfo>
Shih-wei Liao67e37f12012-07-27 03:50:34 -07001153 diag_line_info(TheTarget->createDiagnosticLineInfo(*TheTarget,
Zonr Changaffc1502012-07-16 14:28:23 +08001154 TheTriple.getTriple()));
Zonr Changaffc1502012-07-16 14:28:23 +08001155
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001156 mcld::getDiagnosticEngine().setLineInfo(*diag_line_info.take());
Zonr Changaffc1502012-07-16 14:28:23 +08001157
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001158 // Figure out where we are going to send the output...
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001159 OwningPtr<mcld::ToolOutputFile>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001160 Out(GetOutputStream(TheTarget->get()->getName(),
1161 TheTriple.getOS(),
Zonr Changaffc1502012-07-16 14:28:23 +08001162 ArgFileType,
1163 ArgBitcodeFilename,
1164 ArgOutputFilename));
1165 if (!Out) {
1166 // FIXME: show some error message pls.
1167 return 1;
1168 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001169
1170 // Build up all of the passes that we want to do to the module.
1171 PassManager PM;
1172
1173 // Add the target data from the target machine, if it exists, or the module.
1174 if (const TargetData *TD = TheTargetMachine.getTM().getTargetData())
1175 PM.add(new TargetData(*TD));
1176 else
1177 PM.add(new TargetData(&mod));
1178
1179 // Override default to generate verbose assembly.
1180 TheTargetMachine.getTM().setAsmVerbosityDefault(true);
1181
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001182 {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001183 // Ask the target to add backend passes as necessary.
1184 if( TheTargetMachine.addPassesToEmitFile(PM,
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001185 *Out,
Zonr Changaffc1502012-07-16 14:28:23 +08001186 ArgFileType,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001187 OLvl,
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001188 LDIRModule,
1189 LDConfig,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001190 NoVerify)) {
1191 errs() << argv[0] << ": target does not support generation of this"
1192 << " file type!\n";
1193 return 1;
1194 }
1195
1196 // Before executing passes, print the final values of the LLVM options.
1197 cl::PrintOptionValues();
1198
1199 PM.run(mod);
1200 }
1201
1202 // Declare success.
1203 Out->keep();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001204 return 0;
1205}
1206