152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao/*
252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao * Copyright 2012, The Android Open Source Project
352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao *
452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao * you may not use this file except in compliance with the License.
652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao * You may obtain a copy of the License at
752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao *
852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao *
1052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
1152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
1252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao * See the License for the specific language governing permissions and
1452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao * limitations under the License.
1552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao */
1652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
1752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/AndroidBitcode/ABCCompilerDriver.h"
1852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
1952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include <llvm/Module.h>
2042b88c3b3cdadf6fcd367ee2bc620c0c94bbfe1bShih-wei Liao#include <llvm/Pass.h>
2152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include <llvm/Support/MemoryBuffer.h>
2252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include <llvm/Support/raw_ostream.h>
2356de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#include <mcld/Config/Config.h>
243928c62048612cd7180136017be5b7436c55717cShih-wei Liao
2552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/Config/Config.h"
2652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/Script.h"
2752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/Source.h"
2852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/Support/CompilerConfig.h"
2952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/Support/LinkerConfig.h"
3052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/Support/Log.h"
3152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/Support/OutputFile.h"
3252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/Support/TargetLinkerConfigs.h"
3352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao#include "bcc/Support/TargetCompilerConfigs.h"
3452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
3556de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#if defined(PROVIDE_ARM_CODEGEN)
3656de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao# include "ARM/ARMABCCompilerDriver.h"
3756de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#endif
3856de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#if defined(PROVIDE_MIPS_CODEGEN)
3956de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao# include "Mips/MipsABCCompilerDriver.h"
4056de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#endif
4156de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#if defined(PROVIDE_X86_CODEGEN)
4256de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao# include "X86/X86ABCCompilerDriver.h"
4356de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#endif
4452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
4552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liaonamespace bcc {
4652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
473928c62048612cd7180136017be5b7436c55717cShih-wei LiaoABCCompilerDriver::ABCCompilerDriver(const std::string &pTriple)
4842b88c3b3cdadf6fcd367ee2bc620c0c94bbfe1bShih-wei Liao  : mContext(), mCompiler(*this), mLinker(),
4952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    mCompilerConfig(NULL), mLinkerConfig(NULL),
503928c62048612cd7180136017be5b7436c55717cShih-wei Liao    mTriple(pTriple), mAndroidSysroot("/") {
5152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao}
5252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
5352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei LiaoABCCompilerDriver::~ABCCompilerDriver() {
5452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  delete mCompilerConfig;
5552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  delete mLinkerConfig;
5652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao}
5752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
5852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liaobool ABCCompilerDriver::configCompiler() {
5952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (mCompilerConfig != NULL) {
6052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return true;
6152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
6252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
6352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mCompilerConfig = new (std::nothrow) CompilerConfig(mTriple);
6452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (mCompilerConfig == NULL) {
6552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Out of memory when create the compiler configuration!");
6652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
6752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
6852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
6952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Set PIC mode for relocatables.
7052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mCompilerConfig->setRelocationModel(llvm::Reloc::PIC_);
7152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
7252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Set optimization level to -O1.
7352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mCompilerConfig->setOptimizationLevel(llvm::CodeGenOpt::Less);
7452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
7552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  Compiler::ErrorCode result = mCompiler.config(*mCompilerConfig);
7652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
7752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (result != Compiler::kSuccess) {
7852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Failed to configure the compiler! (detail: %s)",
7952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao          Compiler::GetErrorString(result));
8052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
8152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
8252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
8352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  return true;
8452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao}
8552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
8652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liaobool ABCCompilerDriver::configLinker() {
8752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (mLinkerConfig != NULL) {
8852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return true;
8952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
9052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
9152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinkerConfig = new (std::nothrow) LinkerConfig(mTriple);
9252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (mLinkerConfig == NULL) {
9352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Out of memory when create the linker configuration!");
9452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
9552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
9652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
9752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // FIXME: how can we get the soname if input/output is file descriptor?
9852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinkerConfig->setSOName("");
9952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
10052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinkerConfig->setDyld("/system/bin/linker");
10152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinkerConfig->setSysRoot(mAndroidSysroot);
10252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinkerConfig->addSearchDir("=/system/lib");
10352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
10452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Add non-portable function list. For each function X, linker will rename
10552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // it to X_portable. And X_portable" is implemented in libportable to solve
10652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // portable issues.
10731b7c5664f33fcc335c29d8533537ad3c50fe467Shih-wei Liao  const char **non_portable_func = getNonPortableList();
10831b7c5664f33fcc335c29d8533537ad3c50fe467Shih-wei Liao  if (non_portable_func != NULL) {
10931b7c5664f33fcc335c29d8533537ad3c50fe467Shih-wei Liao    while (*non_portable_func != NULL) {
11031b7c5664f33fcc335c29d8533537ad3c50fe467Shih-wei Liao      mLinkerConfig->addPortable(*non_portable_func);
11131b7c5664f33fcc335c29d8533537ad3c50fe467Shih-wei Liao      non_portable_func++;
11231b7c5664f33fcc335c29d8533537ad3c50fe467Shih-wei Liao    }
11331b7c5664f33fcc335c29d8533537ad3c50fe467Shih-wei Liao  }
11452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
11552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // -shared
11652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinkerConfig->setShared(true);
11752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
11852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // -Bsymbolic.
11952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinkerConfig->setBsymbolic(true);
12052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
12152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Config the linker.
12252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  Linker::ErrorCode result = mLinker.config(*mLinkerConfig);
12352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (result != Linker::kSuccess) {
12452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Failed to configure the linker! (%s)",
12552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao          Linker::GetErrorString(result));
12652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
12752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
12852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
12952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  return true;
13052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao}
13152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
13252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao//------------------------------------------------------------------------------
13352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
13452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei LiaoScript *ABCCompilerDriver::prepareScript(int pInputFd) {
13552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  Source *source = Source::CreateFromFd(mContext, pInputFd);
13652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (source == NULL) {
13752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Failed to load LLVM module from file descriptor `%d'", pInputFd);
13852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return NULL;
13952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
14052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
14152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  Script *script = new (std::nothrow) Script(*source);
14252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (script == NULL) {
14352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Out of memory when create script for file descriptor `%d'!",
14452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao          pInputFd);
14552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    delete source;
14652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return NULL;
14752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
14852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
14952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  return script;
15052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao}
15152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
15252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liaobool ABCCompilerDriver::compile(Script &pScript, llvm::raw_ostream &pOutput) {
15352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Config the compiler.
15452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (!configCompiler()) {
15552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
15652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
15752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
15852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Run the compiler.
15952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  Compiler::ErrorCode result = mCompiler.compile(pScript, pOutput);
16052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (result != Compiler::kSuccess) {
16152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Fatal error during compilation (%s)!",
16252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao          Compiler::GetErrorString(result));
16352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
16452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
16552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
16652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  return true;
16752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao}
16852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
16952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liaobool ABCCompilerDriver::link(const Script &pScript,
17052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao                             const std::string &input_relocatable,
17152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao                             int pOutputFd) {
17252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Config the linker.
17352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (!configLinker()) {
17452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
17552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
17652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
17752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Prepare output file.
17852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  Linker::ErrorCode result = mLinker.setOutput(pOutputFd);
17952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
18052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (result != Linker::kSuccess) {
18152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Failed to open the output file! (file descriptor `%d': %s)",
18252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao          pOutputFd, Linker::GetErrorString(result));
18352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
18452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
18552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
18652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinker.addObject(mAndroidSysroot + "/system/lib/crtbegin_so.o");
18752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
18852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Prepare the relocatables.
18952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //
19052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // FIXME: Ugly const_cast here.
19152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinker.addObject(const_cast<char *>(input_relocatable.data()),
19252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao                    input_relocatable.size());
19352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
19452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Read dependent library list.
19552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  const Source &source = pScript.getSource();
19652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  for (llvm::Module::lib_iterator lib_iter = source.getModule().lib_begin(),
19752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao          lib_end = source.getModule().lib_end(); lib_iter != lib_end;
19852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao       ++lib_iter) {
19952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    mLinker.addNameSpec(*lib_iter);
20052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
20152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
20252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // TODO: Refactor libbcc/runtime/ to libcompilerRT.so and use it.
20352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinker.addNameSpec("bcc");
20452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
20552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  mLinker.addObject(mAndroidSysroot + "/system/lib/crtend_so.o");
20652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
20752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Perform linking.
20852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  result = mLinker.link();
20952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (result != Linker::kSuccess) {
21052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Failed to link the shared object (detail: %s)",
21152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao          Linker::GetErrorString(result));
21252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
21352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
21452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
21552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  return true;
21652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao}
21752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
21852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao//------------------------------------------------------------------------------
21952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
2203928c62048612cd7180136017be5b7436c55717cShih-wei LiaoABCCompilerDriver *ABCCompilerDriver::Create(const std::string &pTriple) {
2213928c62048612cd7180136017be5b7436c55717cShih-wei Liao  std::string error;
2223928c62048612cd7180136017be5b7436c55717cShih-wei Liao  const llvm::Target *target =
2233928c62048612cd7180136017be5b7436c55717cShih-wei Liao      llvm::TargetRegistry::lookupTarget(pTriple, error);
2243928c62048612cd7180136017be5b7436c55717cShih-wei Liao
2253928c62048612cd7180136017be5b7436c55717cShih-wei Liao  if (target == NULL) {
2263928c62048612cd7180136017be5b7436c55717cShih-wei Liao    ALOGE("Unsupported target '%s' (detail: %s)!", pTriple.c_str(),
2273928c62048612cd7180136017be5b7436c55717cShih-wei Liao          error.c_str());
2283928c62048612cd7180136017be5b7436c55717cShih-wei Liao    return NULL;
2293928c62048612cd7180136017be5b7436c55717cShih-wei Liao  }
2303928c62048612cd7180136017be5b7436c55717cShih-wei Liao
2313928c62048612cd7180136017be5b7436c55717cShih-wei Liao  switch (llvm::Triple::getArchTypeForLLVMName(target->getName())) {
23256de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#if defined(PROVIDE_ARM_CODEGEN)
2333928c62048612cd7180136017be5b7436c55717cShih-wei Liao    case llvm::Triple::arm:
2343928c62048612cd7180136017be5b7436c55717cShih-wei Liao    case llvm::Triple::thumb: {
2353928c62048612cd7180136017be5b7436c55717cShih-wei Liao      return new ARMABCCompilerDriver(pTriple);
2363928c62048612cd7180136017be5b7436c55717cShih-wei Liao    }
23756de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#endif
23856de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#if defined(PROVIDE_MIPS_CODEGEN)
2393928c62048612cd7180136017be5b7436c55717cShih-wei Liao    case llvm::Triple::mipsel: {
2403928c62048612cd7180136017be5b7436c55717cShih-wei Liao      return new MipsABCCompilerDriver(pTriple);
2413928c62048612cd7180136017be5b7436c55717cShih-wei Liao    }
24256de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#endif
24356de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#if defined(PROVIDE_X86_CODEGEN)
2443928c62048612cd7180136017be5b7436c55717cShih-wei Liao    case llvm::Triple::x86: {
2453928c62048612cd7180136017be5b7436c55717cShih-wei Liao      return new X86ABCCompilerDriver(pTriple);
2463928c62048612cd7180136017be5b7436c55717cShih-wei Liao    }
24756de4e825771d5f751f62001b70651e9c177e362Shih-wei Liao#endif
2483928c62048612cd7180136017be5b7436c55717cShih-wei Liao    default: {
2493928c62048612cd7180136017be5b7436c55717cShih-wei Liao      ALOGE("Unknown architecture '%s' supplied in %s!", target->getName(),
2503928c62048612cd7180136017be5b7436c55717cShih-wei Liao            pTriple.c_str());
2513928c62048612cd7180136017be5b7436c55717cShih-wei Liao      break;
2523928c62048612cd7180136017be5b7436c55717cShih-wei Liao    }
2533928c62048612cd7180136017be5b7436c55717cShih-wei Liao  }
2543928c62048612cd7180136017be5b7436c55717cShih-wei Liao
2553928c62048612cd7180136017be5b7436c55717cShih-wei Liao  return NULL;
2563928c62048612cd7180136017be5b7436c55717cShih-wei Liao}
2573928c62048612cd7180136017be5b7436c55717cShih-wei Liao
25852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liaobool ABCCompilerDriver::build(int pInputFd, int pOutputFd) {
25952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
26052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Prepare the input.
26152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
26252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  Script *script = prepareScript(pInputFd);
26352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (script == NULL) {
26452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
26552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
26652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
26752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
26852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Prepare the output.
26952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
27052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  std::string output_relocatable;
27152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  llvm::raw_ostream *output =
27252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao      new (std::nothrow) llvm::raw_string_ostream(output_relocatable);
27352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (output == NULL) {
27452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    ALOGE("Failed to prepare the output for compile the input from %d into "
27552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao          "relocatable object!", pInputFd);
27652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    delete script;
27752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
27852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
27952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
28052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
28152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Compile.
28252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
28352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (!compile(*script, *output)) {
28452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    delete output;
28552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    delete script;
28652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
28752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
28852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
28952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
29052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Close the output.
29152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
29252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  delete output;
29352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
29452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
29552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Link.
29652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
29752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  if (!link(*script, output_relocatable, pOutputFd)) {
29852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    delete script;
29952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao    return false;
30052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  }
30152aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
30252aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
30352aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  // Clean up.
30452aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  //===--------------------------------------------------------------------===//
30552aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  delete script;
30652aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
30752aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao  return true;
30852aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao}
30952aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao
31052aefd86e18310cd7e5de81f8498bb3497978519Shih-wei Liao} // namespace bcc
311