1d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao/*
2d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * Copyright 2012, The Android Open Source Project
3d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao *
4d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
5d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * you may not use this file except in compliance with the License.
6d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * You may obtain a copy of the License at
7d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao *
8d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
9d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao *
10d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
11d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
12d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * See the License for the specific language governing permissions and
14d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * limitations under the License.
15d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao */
16d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
17d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <string>
18d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <vector>
19d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
20d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <stdlib.h>
21d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
22d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/ADT/STLExtras.h>
23d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/ADT/SmallString.h>
24d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Config/config.h>
25d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/CommandLine.h>
26d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/FileSystem.h>
27d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/Path.h>
28d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/raw_ostream.h>
29d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/system_error.h>
30d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
31d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/BCCContext.h>
32d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Compiler.h>
33d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Config/BuildInfo.h>
34d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Config/Config.h>
35d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/ExecutionEngine/BCCRuntimeSymbolResolver.h>
36d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/ExecutionEngine/ObjectLoader.h>
37d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/ExecutionEngine/SymbolResolverProxy.h>
38d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/ExecutionEngine/SymbolResolvers.h>
39d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Script.h>
40d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Source.h>
41d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/CompilerConfig.h>
42d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/Initialization.h>
43d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/InputFile.h>
44d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/OutputFile.h>
45d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/TargetCompilerConfigs.h>
46d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
47d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaousing namespace bcc;
48d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
49d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
50d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// General Options
51d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
52d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaonamespace {
53d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
54d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::list<std::string>
55d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptInputFilenames(llvm::cl::Positional, llvm::cl::OneOrMore,
56d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                  llvm::cl::desc("<input bitcode files>"));
57d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
58d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<std::string>
59d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptOutputFilename("o", llvm::cl::desc("Specify the output filename"),
60d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                  llvm::cl::value_desc("filename"));
61d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
62d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#ifdef TARGET_BUILD
63d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaoconst std::string OptTargetTriple(DEFAULT_TARGET_TRIPLE_STRING);
64d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#else
65d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<std::string>
66d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptTargetTriple("mtriple",
67d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                llvm::cl::desc("Specify the target triple (default: "
68d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                               DEFAULT_TARGET_TRIPLE_STRING ")"),
69d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING),
70d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                llvm::cl::value_desc("triple"));
71d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
72d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden,
73d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                 llvm::cl::desc("Alias for -mtriple"),
74d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                 llvm::cl::aliasopt(OptTargetTriple));
75d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#endif
76d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
77d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
78d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Compiler Options
79d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
80d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<bool>
81d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptPIC("fPIC", llvm::cl::desc("Generate fully relocatable, position independent"
82d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                              " code"));
83d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
84d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<char>
85d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptOptLevel("O", llvm::cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
86d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                "(default: -O2)"),
87d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao            llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::init('2'));
88d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
89d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<bool>
90d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptC("c", llvm::cl::desc("Compile and assemble, but do not link."));
91d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
92d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
93d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Linker Options
94d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
95d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// FIXME: this option will be removed in the future when MCLinker is capable
96d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//        of generating shared library directly from given bitcode. It only
97d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//        takes effect when -shared is supplied.
98d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<std::string>
99d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptImmObjectOutput("or", llvm::cl::desc("Specify the filename for output the "
100d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                        "intermediate relocatable when linking "
101d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                        "the input bitcode to the shared "
102d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                        "library"), llvm::cl::ValueRequired);
103d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
104d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<bool>
105d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptShared("shared", llvm::cl::desc("Create a shared library from input bitcode "
106d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                   "files"));
107d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
108d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
109d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
110d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Loader Options
111d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
112d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<bool>
113d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptRunEntry("R", llvm::cl::desc("Run the entry method after successfully load "
114d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                "and compile."));
115d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
116d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<std::string>
117d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptEntryFunction("entry-function", llvm::cl::desc("Specify the entry function "
118d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                                  "for -R (default: main)"),
119d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                 llvm::cl::value_desc("function"), llvm::cl::init("main"));
120d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
121d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<bool>
122d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptEnableGDB("enable-gdb", llvm::cl::desc("Enable GDB JIT debugging when "
123d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                          "runs the entry method"));
124d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
125d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::list<std::string>
126d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptRuntimeLibs("load", llvm::cl::desc("Specify the shared libraries for "
127d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                      "execution (e.g., -load=c will search "
128d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                      "and load libc.so for execution)"),
129d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao               llvm::cl::ZeroOrMore, llvm::cl::value_desc("namespec"));
130d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
131d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Override "bcc -version" since the LLVM version information is not correct on
132d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Android build.
133d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaovoid BCCVersionPrinter() {
134d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::raw_ostream &os = llvm::outs();
135d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  os << "libbcc (The Android Open Source Project, http://www.android.com/):\n"
136d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao     << "  Build time: " << BuildInfo::GetBuildTime() << "\n"
137d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao     << "  Build revision: " << BuildInfo::GetBuildRev() << "\n"
138d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao     << "  Build source blob: " << BuildInfo::GetBuildSourceBlob() << "\n"
139d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao     << "  Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n";
140d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
141d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  os << "\n";
142d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
143d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  os << "LLVM (http://llvm.org/):\n"
144d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao     << "  Version: " << PACKAGE_VERSION << "\n";
145d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return;
146d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
147d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
148d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao} // end anonymous namespace
149d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
150d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaostatic inline
151d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoScript *PrepareScript(BCCContext &pContext,
152d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                      const llvm::cl::list<std::string> &pBitcodeFiles) {
153d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  Script *result = NULL;
154d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
155d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  for (unsigned i = 0; i < pBitcodeFiles.size(); i++) {
156d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    const std::string &input_bitcode = pBitcodeFiles[i];
157d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    Source *source = Source::CreateFromFile(pContext, input_bitcode);
158d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    if (source == NULL) {
159d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      llvm::errs() << "Failed to load llvm module from file `" << input_bitcode
160d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                   << "'!\n";
161d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      return NULL;
162d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    }
163d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
164d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    if (result != NULL) {
165d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      if (!result->mergeSource(*source, /* pPreserveSource */false)) {
166d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        llvm::errs() << "Failed to merge the llvm module `" << input_bitcode
167d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                     << "' to compile!\n";
168d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        delete source;
169d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        return NULL;
170d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      }
171d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    } else {
172d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      result = new (std::nothrow) Script(*source);
173d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      if (result == NULL) {
174d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        llvm::errs() << "Out of memory when create script for file `"
175d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                     << input_bitcode << "'!\n";
176d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        delete source;
177d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        return NULL;
178d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      }
179d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    }
180d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
181d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
182d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return result;
183d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
184d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
185d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaostatic inline
186d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaobool ConfigCompiler(Compiler &pCompiler) {
187d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  CompilerConfig *config = NULL;
188d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
189d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#ifdef TARGET_BUILD
190d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  config = new (std::nothrow) DefaultCompilerConfig();
191d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#else
192d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  config = new (std::nothrow) CompilerConfig(OptTargetTriple);
193d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#endif
194d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (config == NULL) {
195d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Out of memory when create the compiler configuration!\n";
196d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
197d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
198d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
199d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Setup the config according to the valud of command line option.
200d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (OptPIC) {
201d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    config->setRelocationModel(llvm::Reloc::PIC_);
202d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
203d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  switch (OptOptLevel) {
204d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    case '0': config->setOptimizationLevel(llvm::CodeGenOpt::None); break;
205d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    case '1': config->setOptimizationLevel(llvm::CodeGenOpt::Less); break;
206d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    case '3': config->setOptimizationLevel(llvm::CodeGenOpt::Aggressive); break;
207d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    case '2':
208d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    default: {
209d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      config->setOptimizationLevel(llvm::CodeGenOpt::Default);
210d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      break;
211d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    }
212d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
213d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
214d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  Compiler::ErrorCode result = pCompiler.config(*config);
215d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
216d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  delete config;
217d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
218d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (result != Compiler::kSuccess) {
219d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Failed to configure the compiler! (detail: "
220d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                 << Compiler::GetErrorString(result) << ")\n";
221d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
222d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
223d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
224d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return true;
225d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
226d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
227d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#define DEFAULT_OUTPUT_PATH   "/sdcard/a.out"
228d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaostatic inline
229d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaostd::string DetermineOutputFilename(const std::string &pOutputPath) {
230d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (!pOutputPath.empty()) {
231d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return pOutputPath;
232d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
233d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
234d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // User doesn't specify the value to -o.
235d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (OptInputFilenames.size() > 1) {
236d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Use " DEFAULT_OUTPUT_PATH " for output file!\n";
237d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return DEFAULT_OUTPUT_PATH;
238d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
239d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
240d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // There's only one input bitcode file.
241d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  const std::string &input_path = OptInputFilenames[0];
242d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::SmallString<200> output_path(input_path);
243d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
244d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::error_code err = llvm::sys::fs::make_absolute(output_path);
245d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (err != llvm::errc::success) {
246d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Failed to determine the absolute path of `" << input_path
247d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                 << "'! (detail: " << err.message() << ")\n";
248d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return "";
249d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
250d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
251d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (OptC) {
252d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    // -c was specified. Replace the extension to .o.
253d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::sys::path::replace_extension(output_path, "o");
254d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  } else {
255d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    // Use a.out under current working directory when compile executable or
256d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    // shared library.
257d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::sys::path::remove_filename(output_path);
258d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::sys::path::append(output_path, "a.out");
259d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
260d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
261d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return output_path.c_str();
262d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
263d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
264d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaostatic inline
265d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaobool CompileScript(Compiler &pCompiler, Script &pScript,
266d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                   const std::string &pOutputPath) {
267d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Open the output file.
268c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao  OutputFile output_file(pOutputPath, FileBase::kTruncate);
269d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
270d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (output_file.hasError()) {
271d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Failed to open the output file `" << pOutputPath
272d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                 << "'! (detail: " << output_file.getErrorMessage() << ")\n";
273d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
274d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
275d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
276d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Run the compiler.
277d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  Compiler::ErrorCode result = pCompiler.compile(pScript, output_file);
278d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (result != Compiler::kSuccess) {
279d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Fatal error during compilation (detail: "
280d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                 << Compiler::GetErrorString(result) << ".)\n";
281d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
282d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
283d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
284d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return true;
285d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
286d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
287d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaostatic inline
288d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaobool PrepareRuntimes(std::vector<SymbolResolverInterface *> &pRuntimes) {
289d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::SmallVector<const char *, 2> search_paths;
290d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
291d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#ifdef TARGET_BUILD
292d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  search_paths.push_back("/system/lib/");
293d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#else
294d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  search_paths.push_back("/lib/");
295d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  search_paths.push_back("/usr/lib/");
296d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#endif
297d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
298d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Most of the following lines comes from llvm/tools/llvm-ld.cpp.
299d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  for (unsigned i = 0; i < OptRuntimeLibs.size(); i++) {
300d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    const std::string &lib = OptRuntimeLibs[i];
301d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::sys::Path lib_path;
302d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    for (llvm::SmallVectorImpl<const char *>::const_iterator
303d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao             search_path_iter = search_paths.begin(),
304d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao             search_path_end = search_paths.end();
305d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao         search_path_iter != search_path_end; search_path_iter++) {
306d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
307d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      lib_path = *search_path_iter;
308d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      lib_path.appendComponent("lib" + lib);
309d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      lib_path.appendSuffix(llvm::sys::Path::GetDLLSuffix());
310d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
311d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      if (lib_path.isEmpty()) {
312d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        if (!lib_path.isDynamicLibrary()) {
313d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao          lib_path = llvm::sys::Path();
314d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        } else {
315d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao          break;
316d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        }
317d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      }
318d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    } // for each search_paths
319d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    if (lib_path.isEmpty()) {
320d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      // FIXME: llvm::sys::Path::FindLibrary(...) is able to consume
321d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      //        'const std::string &' instead of 'std::string &'.
322d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      std::string lib_tmp = lib;
323d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      lib_path = llvm::sys::Path::FindLibrary(lib_tmp);
324d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    }
325d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    if (lib_path.isEmpty()) {
326d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      llvm::errs() << "Unable to find `lib" << lib << "' for execution!\n";
327d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      llvm::DeleteContainerPointers(pRuntimes);
328d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      return false;
329d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    } else {
330d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      DyldSymbolResolver *dyld_resolver =
331d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao          new (std::nothrow) DyldSymbolResolver(lib_path.str().c_str());
332d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
333d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      if (dyld_resolver != NULL) {
334d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        pRuntimes.push_back(dyld_resolver);
335d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      } else {
336d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        llvm::errs() << "Out of memory when load `" << lib_path.str() << "'!\n";
337d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        llvm::DeleteContainerPointers(pRuntimes);
338d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao        return false;
339d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      }
340d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    }
341d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  } // for each OptRuntimeLibs
342d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
343d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return true;
344d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
345d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
346d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaostatic inline
347d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaobool LoadAndRun(const std::string &pOutputExecutable) {
348d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  SymbolResolverProxy runtime_resolver;
349d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
350d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Include compiler runtime.
351d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  BCCRuntimeSymbolResolver bcc_runtimes;
352d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  runtime_resolver.chainResolver(bcc_runtimes);
353d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
354d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Open the output file for execution.
355d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  InputFile input_exec(pOutputExecutable);
356d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (input_exec.hasError()) {
357d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Failed to open the executable `" << pOutputExecutable
358d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                 << "'! (detail: " << input_exec.getErrorMessage() << ")\n";
359d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
360d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
361d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
362d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Load the runtime libraries given in command line.
363d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  std::vector<SymbolResolverInterface *> lib_runtimes;
364d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (!PrepareRuntimes(lib_runtimes)) {
365d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
366d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
367d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
368d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  for (std::vector<SymbolResolverInterface *>::const_iterator
369d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao           librt_iter = lib_runtimes.begin(), librt_end = lib_runtimes.end();
370d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao       librt_iter != librt_end; librt_iter++) {
371d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    runtime_resolver.chainResolver(*(*librt_iter));
372d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
373d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
374d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Load the output file.
375d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  ObjectLoader *loader = ObjectLoader::Load(input_exec, runtime_resolver,
376d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                            OptEnableGDB);
377d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (loader == NULL) {
378d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Failed to load `" << pOutputExecutable << "'!\n";
379d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::DeleteContainerPointers(lib_runtimes);
380d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
381d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
382d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
383d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Retrieve the address of entry function.
384d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  void *entry = loader->getSymbolAddress(OptEntryFunction.c_str());
385d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (entry == NULL) {
386d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Couldn't find entry method `" << OptEntryFunction
387d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                 << "' in " << pOutputExecutable << "' for execution!\n";
388d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    delete loader;
389d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::DeleteContainerPointers(lib_runtimes);
390d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
391d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
392d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
393d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Execute the entry function.
394d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  int run_result = reinterpret_cast<int (*)()>(entry)();
395d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::errs() << "result: " << run_result << "\n";
396d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
397d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  // Clean up.
398d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  delete loader;
399d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::DeleteContainerPointers(lib_runtimes);
400d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
401d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return true;
402d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
403d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
404d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaoint main(int argc, char **argv) {
405d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::cl::SetVersionPrinter(BCCVersionPrinter);
406d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::cl::ParseCommandLineOptions(argc, argv);
407d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  init::Initialize();
408d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
409d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  BCCContext context;
410d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  Compiler compiler;
411d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
412d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  Script *script = PrepareScript(context, OptInputFilenames);
413d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (script == NULL) {
414d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return EXIT_FAILURE;
415d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
416d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
417d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (!ConfigCompiler(compiler)) {
418d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return EXIT_FAILURE;
419d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
420d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
421d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  std::string OutputFilename = DetermineOutputFilename(OptOutputFilename);
422d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (OutputFilename.empty()) {
423d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return EXIT_FAILURE;
424d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
425d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
426d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (!CompileScript(compiler, *script, OutputFilename)) {
427d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return EXIT_FAILURE;
428d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
429d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
430d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (OptRunEntry && !LoadAndRun(OutputFilename)) {
431d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return EXIT_FAILURE;
432d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
433d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
434d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return EXIT_SUCCESS;
435d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
436