main.cpp revision affc150dc44fab1911775a49636d0ce85333b634
1affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===- mcld.cpp -----------------------------------------------------------===//
2affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
3affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//                     The MCLinker Project
4affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
5affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This file is distributed under the University of Illinois Open Source
6affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// License. See LICENSE.TXT for details.
7affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
8affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
9affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <stdlib.h>
10affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <string>
11affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
12affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/ADT/SmallString.h>
13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/CommandLine.h>
14affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/FileSystem.h>
15affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/Path.h>
16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/raw_ostream.h>
17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/system_error.h>
18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
19affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Config/Config.h>
20affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Support/LinkerConfig.h>
21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Support/Initialization.h>
22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Support/TargetLinkerConfigs.h>
23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Linker.h>
24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
25affc150dc44fab1911775a49636d0ce85333b634Zonr Changusing namespace alone;
26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
27affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
28affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Compiler Options
29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
30affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#ifdef TARGET_BUILD
31affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst std::string OptTargetTripe(DEFAULT_TARGET_TRIPLE_STRING);
32affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#else
33affc150dc44fab1911775a49636d0ce85333b634Zonr Changllvm::cl::opt<std::string>
34affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptTargetTriple("mtriple",
35affc150dc44fab1911775a49636d0ce85333b634Zonr Chang               llvm::cl::desc("Specify the target triple (default: "
36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              DEFAULT_TARGET_TRIPLE_STRING ")"),
37affc150dc44fab1911775a49636d0ce85333b634Zonr Chang               llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING),
38affc150dc44fab1911775a49636d0ce85333b634Zonr Chang               llvm::cl::value_desc("triple"));
39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
40affc150dc44fab1911775a49636d0ce85333b634Zonr Changllvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden,
41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                llvm::cl::desc("Alias for -mtriple"),
42affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                llvm::cl::aliasopt(OptTargetTriple));
43affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#endif
44affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
45affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Command Line Options
47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// There are four kinds of command line options:
48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//   1. input, (may be a file, such as -m and /tmp/XXXX.o.)
49affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//   2. scripting options, (represent a subset of link scripting language, such
50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//      as --defsym.)
51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//   3. and general options. (the rest of options)
52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// General Options
54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
55affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<std::string>
56affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptOutputFilename("o",
57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                  llvm::cl::desc("Output filename"),
58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                  llvm::cl::value_desc("filename"));
59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
60affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<std::string>
61affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptSysRoot("sysroot",
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang           llvm::cl::desc("Use directory as the location of the sysroot, overriding "
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                    "the configure-time default."),
64affc150dc44fab1911775a49636d0ce85333b634Zonr Chang           llvm::cl::value_desc("directory"),
65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang           llvm::cl::ValueRequired);
66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
67affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::list<std::string>
68affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptSearchDirList("L",
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                 llvm::cl::ZeroOrMore,
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                 llvm::cl::desc("Add path searchdir to the list of paths that ld will "
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                          "search for archive libraries and ld control scripts."),
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                 llvm::cl::value_desc("searchdir"),
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                 llvm::cl::Prefix);
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
75affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<std::string>
76affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptSOName("soname",
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          llvm::cl::desc("Set internal name of shared library"),
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          llvm::cl::value_desc("name"));
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
81affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<bool>
82affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptShared("shared",
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          llvm::cl::desc("Create a shared library."),
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          llvm::cl::init(false));
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
86affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<std::string>
87affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptDyld("dynamic-linker",
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        llvm::cl::desc("Set the name of the dynamic linker."),
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        llvm::cl::value_desc("Program"));
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Inputs
93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
94affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::list<std::string>
95affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptInputObjectFiles(llvm::cl::Positional,
96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                    llvm::cl::desc("[input object files]"),
97affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                    llvm::cl::ZeroOrMore);
98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
99affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::list<std::string>
100affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptNameSpecList("l",
101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                llvm::cl::ZeroOrMore,
102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                llvm::cl::desc("Add the archive or object file specified by "
103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                               "namespec to the list of files to link."),
104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                llvm::cl::value_desc("namespec"),
105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                llvm::cl::Prefix);
106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Scripting Options
109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
110affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::list<std::string>
111affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptWrapList("wrap",
112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            llvm::cl::ZeroOrMore,
113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            llvm::cl::desc("Use a wrap function fo symbol."),
114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            llvm::cl::value_desc("symbol"));
115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Helper Functions
118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Override "mcld -version"
120affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid MCLDVersionPrinter() {
121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::raw_ostream &os = llvm::outs();
122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  os << "mcld (The MCLinker Project, http://mclinker.googlecode.com/):\n"
123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang     << "  Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n";
124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  os << "\n";
126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  os << "LLVM (http://llvm.org/):\n";
128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return;
129affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#define DEFAULT_OUTPUT_PATH "a.out"
132affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic inline
133affc150dc44fab1911775a49636d0ce85333b634Zonr Changstd::string DetermineOutputFilename(const std::string pOutputPath)
134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
135affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (!pOutputPath.empty()) {
136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return pOutputPath;
137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // User does't specify the value to -o
140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (OptInputObjectFiles.size() > 1) {
141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    llvm::errs() << "Use " DEFAULT_OUTPUT_PATH " for output file!\n";
142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return DEFAULT_OUTPUT_PATH;
143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // There's only one input file
146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const std::string &input_path = OptInputObjectFiles[0];
147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::SmallString<200> output_path(input_path);
148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::error_code err = llvm::sys::fs::make_absolute(output_path);
150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (llvm::errc::success != err) {
151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    llvm::errs() << "Failed to determine the absolute path of `" << input_path
152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                 << "'! (detail: " << err.message() << ")\n";
153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return "";
154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::sys::path::remove_filename(output_path);
157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::sys::path::append(output_path, "a.out");
158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return output_path.c_str();
160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
162affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic inline
163affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool ConfigLinker(Linker &pLinker, const std::string &pOutputFilename)
164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LinkerConfig* config = NULL;
166affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
167affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#ifdef TARGET_BUILD
168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  config = new (std::nothrow) DefaultLinkerConfig();
169affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#else
170affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  config = new (std::nothrow) LinkerConfig(OptTargetTriple);
171affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#endif
172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (config == NULL) {
173affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    llvm::errs() << "Out of memory when create the linker configuration!\n";
174affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
175affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Setup the configuration accroding to the value of command line options.
178affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 1. set up soname
179affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (!OptSOName.empty())
180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    config->setSOName(OptSOName);
181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    config->setSOName(pOutputFilename);
183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
184affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 2. if given, set up sysroot
185affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (!OptSysRoot.empty())
186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    config->setSysRoot(OptSysRoot);
187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 3. if given, set up dynamic linker path.
189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (!OptDyld.empty())
190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    config->setDyld(OptDyld);
191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 4. if given, set up wrapped symbols
193affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::list<std::string>::iterator wrap, wEnd = OptWrapList.end();
194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (wrap = OptWrapList.begin(); wrap != wEnd; ++wrap)
195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    config->addWrap(*wrap);
196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // 5. if given, set up search directories
198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::list<std::string>::iterator sdir, sdirEnd = OptSearchDirList.end();
199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (sdir = OptSearchDirList.begin(); sdir != sdirEnd; ++sdir)
200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    config->addSearchDir(*sdir);
201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  Linker::ErrorCode result = pLinker.config(*config);
203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Linker::kSuccess != result) {
205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    llvm::errs() << "Failed to configure the linker! (detail: "
206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                << Linker::GetErrorString(result) << ")\n";
207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
213affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic inline
214affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool PrepareInputOutput(Linker& pLinker, const std::string &pOutputPath)
215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  set output  ----- //
217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: In MCLinker, we have to set up output before setting up inputs.
218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // This constraint is wired, and we should break this constraint.
219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  Linker::ErrorCode result = pLinker.setOutput(pOutputPath);
220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Linker::kSuccess != result) {
222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    llvm::errs() << "Failed to open the output file! (detail: "
223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                 << pOutputPath << ": "
224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                 << Linker::GetErrorString(result) << ")\n";
225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
228affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  set inputs  ----- //
229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::list<std::string>::iterator fileIt = OptInputObjectFiles.begin();
230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::list<std::string>::iterator libIt  = OptNameSpecList.begin();
231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::list<std::string>::iterator fileBegin = OptInputObjectFiles.begin();
233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::list<std::string>::iterator libBegin = OptNameSpecList.begin();
234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::list<std::string>::iterator fileEnd = OptInputObjectFiles.end();
235affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::list<std::string>::iterator libEnd = OptNameSpecList.end();
236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
237affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  unsigned libPos = 0, filePos = 0;
238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  while (true) {
239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (libIt != libEnd)
240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      libPos = OptNameSpecList.getPosition(libIt - libBegin);
241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      libPos = 0;
243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (fileIt != fileEnd)
245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      filePos = OptInputObjectFiles.getPosition(fileIt - fileBegin);
246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      filePos = 0;
248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if ( filePos != 0 && (libPos == 0 || filePos < libPos) ) {
250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      result = pLinker.addObject(*fileIt);
251affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (Linker::kSuccess != result) {
252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        llvm::errs() << "Failed to open the input file! (detail: "
253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     << *fileIt << ": "
254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     << Linker::GetErrorString(result) << ")\n";
255affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        return false;
256affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
257affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      ++fileIt;
258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
259affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else if ( libPos != 0 && (filePos == 0 || libPos < filePos) ) {
260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      result = pLinker.addNameSpec(*libIt);
261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (Linker::kSuccess != result) {
262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        llvm::errs() << "Failed to open the namespec! (detail: "
263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     << *libIt << ": "
264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     << Linker::GetErrorString(result) << ")\n";
265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        return false;
266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      ++libIt;
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    else
271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break; // we're done with the list
272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
277affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic inline
278affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool LinkFiles(Linker& pLinker) {
279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  Linker::ErrorCode result = pLinker.link();
280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (Linker::kSuccess != result) {
281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    llvm::errs() << "Failed to linking! (detail: "
282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                 << Linker::GetErrorString(result) << "\n";
283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return false;
284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
288affc150dc44fab1911775a49636d0ce85333b634Zonr Changint main(int argc, char* argv[])
289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::SetVersionPrinter(MCLDVersionPrinter);
291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  llvm::cl::ParseCommandLineOptions(argc, argv);
292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  init::Initialize();
293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  std::string OutputFilename = DetermineOutputFilename(OptOutputFilename);
295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (OutputFilename.empty()) {
296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return EXIT_FAILURE;
297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  Linker linker;
300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (!ConfigLinker(linker, OutputFilename)) {
301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return EXIT_FAILURE;
302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (!PrepareInputOutput(linker, OutputFilename)) {
305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return EXIT_FAILURE;
306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (!LinkFiles(linker)) {
309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return EXIT_FAILURE;
310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return EXIT_SUCCESS;
312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
314