193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao/* 293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * Copyright 2010-2012, The Android Open Source Project 393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * 493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License"); 593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * you may not use this file except in compliance with the License. 693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * You may obtain a copy of the License at 793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * 893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * http://www.apache.org/licenses/LICENSE-2.0 993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * 1093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * Unless required by applicable law or agreed to in writing, software 1193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS, 1293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * See the License for the specific language governing permissions and 1493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao * limitations under the License. 1593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao */ 1693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 1793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include "bcc/Linker.h" 1893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include "bcc/Support/LinkerConfig.h" 1993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include "bcc/Support/MemoryFactory.h" 2093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include "bcc/Support/Log.h" 2193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 2293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include <llvm/Support/ELF.h> 2393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 24f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao#include <mcld/MC/MCLDDriver.h> 2503547495b607bb2293a884c0335fe234de49e1ddShih-wei Liao#include <mcld/MC/InputTree.h> 2693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include <mcld/MC/MCLinker.h> 2793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include <mcld/MC/InputTree.h> 2893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include <mcld/LD/LDSection.h> 2993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include <mcld/LD/LDContext.h> 3093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include <mcld/Target/TargetLDBackend.h> 3193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include <mcld/Support/Path.h> 3293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include <mcld/Support/MemoryArea.h> 3393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao#include <mcld/Support/FileHandle.h> 34f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao#include <mcld/Support/MemoryAreaFactory.h> 35f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao#include <mcld/Support/TargetRegistry.h> 3693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 3793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaousing namespace bcc; 3893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 3993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoconst char* Linker::GetErrorString(enum Linker::ErrorCode pErrCode) { 4093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao static const char* ErrorString[] = { 4193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kSuccess */ 4293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Successfully compiled.", 4393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kDoubleConfig */ 4493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Configure Linker twice.", 4593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kCreateBackend */ 4693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Cannot create backend.", 4793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kDelegateLDInfo */ 4893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Cannot get linker information", 498fe71dd4cd49c426cafa73ab21ab7a95dd15254aShih-wei Liao /* kFindNameSpec */ 508fe71dd4cd49c426cafa73ab21ab7a95dd15254aShih-wei Liao "Cannot find -lnamespec", 5193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kOpenNameSpec */ 5293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Cannot open -lnamespec", 5393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kOpenObjectFile */ 5493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Cannot open object file", 5593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kNotConfig */ 5693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Linker::config() is not called", 5793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kNotSetUpOutput */ 5893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Linker::setOutput() is not called before add input files", 5993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kOpenOutput */ 6093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Cannot open output file", 6193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kReadSections */ 6293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Cannot read sections", 6393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kReadSymbols */ 6493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Cannot read symbols", 6593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kAddAdditionalSymbols */ 6693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "Cannot add standard and target symbols", 6793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao /* kMaxErrorCode */ 6893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "(Unknown error code)" 6993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao }; 7093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 7193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (pErrCode > kMaxErrorCode) { 7293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao pErrCode = kMaxErrorCode; 7393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 7493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 7593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return ErrorString[ static_cast<size_t>(pErrCode) ]; 7693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 7793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 7893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao//===----------------------------------------------------------------------===// 7993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao// Linker 8093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao//===----------------------------------------------------------------------===// 8193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei LiaoLinker::Linker() 8293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL), 83f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao mRoot(NULL), mShared(false) { 8493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 8593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 8693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei LiaoLinker::Linker(const LinkerConfig& pConfig) 8793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL), 88f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao mRoot(NULL), mShared(false) { 8993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 9093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao const std::string &triple = pConfig.getTriple(); 9193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 9293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao enum ErrorCode err = config(pConfig); 9393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (kSuccess != err) { 9493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao ALOGE("%s (%s)", GetErrorString(err), triple.c_str()); 9593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return; 9693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 9793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 9893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return; 9993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 10093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 10193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei LiaoLinker::~Linker() { 10293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao delete mDriver; 10393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao delete mBackend; 10493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao delete mMemAreaFactory; 105f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao delete mRoot; 10693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 10793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 10893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig) { 10993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mLDInfo = const_cast<mcld::MCLDInfo*>(pConfig.getLDInfo()); 11093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (mLDInfo == NULL) { 11193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kDelegateLDInfo; 11293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 11393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 114f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao mRoot = new mcld::InputTree::iterator(mLDInfo->inputs().root()); 11593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mShared = pConfig.isShared(); 11693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mSOName = pConfig.getSOName(); 11793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 11893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kSuccess; 11993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 12093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 12193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::config(const LinkerConfig& pConfig) { 12293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (mLDInfo != NULL) { 12393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kDoubleConfig; 12493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 12593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 12693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao extractFiles(pConfig); 12793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 12893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mBackend = pConfig.getTarget()->createLDBackend(pConfig.getTriple()); 12993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (mBackend == NULL) { 13093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kCreateBackend; 13193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 13293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 13393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mMemAreaFactory = new MemoryFactory(); 13493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 13503547495b607bb2293a884c0335fe234de49e1ddShih-wei Liao mDriver = new mcld::MCLDDriver(*mLDInfo, *mBackend, *mMemAreaFactory); 13603547495b607bb2293a884c0335fe234de49e1ddShih-wei Liao 13793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->initMCLinker(); 13893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 13993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kSuccess; 14093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 14193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 14293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaovoid Linker::advanceRoot() { 143f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao if (mRoot->isRoot()) { 144f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao mRoot->move<mcld::TreeIteratorBase::Leftward>(); 14593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } else { 146f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao mRoot->move<mcld::TreeIteratorBase::Rightward>(); 14793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 14893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return; 14993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 15093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 15193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::openFile(const mcld::sys::fs::Path& pPath, 15293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao enum Linker::ErrorCode pCode, 15393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input& pInput) { 15493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pPath, 15593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::FileHandle::ReadOnly); 15693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 15793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (input_memory->handler()->isGood()) { 15893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao pInput.setMemArea(input_memory); 15993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } else { 16093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return pCode; 16193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 16293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 16393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::LDContext *input_context = mLDInfo->contextFactory().produce(pPath); 16493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao pInput.setContext(input_context); 16593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kSuccess; 16693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 16793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 16893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec) { 16993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::sys::fs::Path* path = NULL; 17093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // find out the real path of the namespec. 17193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (mLDInfo->attrFactory().constraint().isSharedSystem()) { 17293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // In the system with shared object support, we can find both archive 17393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // and shared object. 17493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 17593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (mLDInfo->attrFactory().last().isStatic()) { 17693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // with --static, we must search an archive. 17793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao path = mLDInfo->options().directories().find(pNameSpec, 17893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input::Archive); 17993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 18093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao else { 18193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // otherwise, with --Bdynamic, we can find either an archive or a 18293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // shared object. 18393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao path = mLDInfo->options().directories().find(pNameSpec, 18493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input::DynObj); 18593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 18693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 18793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao else { 18893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // In the system without shared object support, we only look for an 18993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // archive. 19093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao path = mLDInfo->options().directories().find(pNameSpec, 19193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input::Archive); 19293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 19393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 1948fe71dd4cd49c426cafa73ab21ab7a95dd15254aShih-wei Liao if (NULL == path) 1958fe71dd4cd49c426cafa73ab21ab7a95dd15254aShih-wei Liao return kFindNameSpec; 1968fe71dd4cd49c426cafa73ab21ab7a95dd15254aShih-wei Liao 19793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input* input = mLDInfo->inputFactory().produce(pNameSpec, *path, 1988fe71dd4cd49c426cafa73ab21ab7a95dd15254aShih-wei Liao mcld::Input::Unknown); 199f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input); 20093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 20193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao advanceRoot(); 20293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 20393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return openFile(*path, kOpenNameSpec, *input); 20493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 20593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 20693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao/// addObject - Add a object file by the filename. 20793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath) { 20893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input* input = mLDInfo->inputFactory().produce(pObjectPath, 20993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao pObjectPath, 21093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input::Unknown); 21193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 212f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input); 21393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 21493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao advanceRoot(); 21593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 21693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return openFile(pObjectPath, kOpenObjectFile, *input); 21793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 21893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 21993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao/// addObject - Add a piece of memory. The memory is of ELF format. 22093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize) { 22193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 22293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input* input = mLDInfo->inputFactory().produce("memory object", 22393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "NAN", 22493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input::Unknown); 22593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 226f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input); 22793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 22893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao advanceRoot(); 22993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 23093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize); 23193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao input->setMemArea(input_memory); 23293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 23393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::LDContext *input_context = mLDInfo->contextFactory().produce(); 23493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao input->setContext(input_context); 23593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 23693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kSuccess; 23793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 23893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 23993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize) { 24093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input* input = mLDInfo->inputFactory().produce("code object", 24193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao "NAN", 24293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::Input::External); 24393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 244f0407796f0c3e16065db7fd61a2b09e27aaac24dShih-wei Liao mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input); 24593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 24693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao advanceRoot(); 24793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 24893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize); 24993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao input->setMemArea(input_memory); 25093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 25193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::LDContext *input_context = mLDInfo->contextFactory().produce(); 25293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao input->setContext(input_context); 25393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 25493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // FIXME: So far, MCLinker must set up output before add input files. 25593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // set up LDContext 25693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (mDriver->hasInitLinker()) { 25793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kNotConfig; 25893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 25993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 26093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (!mLDInfo->output().hasContext()) { 26193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kNotSetUpOutput; 26293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 26393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 26493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // create NULL section 26593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::LDSection& null = 26693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->getLinker()->createSectHdr("", 26793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::LDFileFormat::Null, 26893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao llvm::ELF::SHT_NULL, 26993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 0); 27093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 27193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao null.setSize(0); 27293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao null.setOffset(0); 27393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao null.setIndex(0); 27493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao null.setInfo(0); 27593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao null.setAlign(0); 27693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 27793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao input_context->getSectionTable().push_back(&null); 27893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 27993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // create .text section 28093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::LDSection& text = mDriver->getLinker()->createSectHdr(".text", 28193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::LDFileFormat::Regular, 28293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao llvm::ELF::SHT_PROGBITS, 28393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR); 28493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 28593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao text.setSize(pSize); 28693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao text.setOffset(0x0); 28793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao text.setIndex(1); 28893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao text.setInfo(0); 28993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao text.setAlign(1); 29093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 29193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao input_context->getSectionTable().push_back(&text); 29293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 29393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kSuccess; 29493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 29593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 29693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::setOutput(const std::string &pPath) { 29793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (mLDInfo->output().hasContext()) { 29893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kDoubleConfig; 29993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 30093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 30193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // ----- initialize output file ----- // 30293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 30393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::FileHandle::Permission perm = 0755; 30493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 30593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::MemoryArea* out_area = mMemAreaFactory->produce( 30693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao pPath, 30793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::FileHandle::ReadWrite | 30893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::FileHandle::Truncate | 30993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::FileHandle::Create, 31093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao perm); 31193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 31293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (!out_area->handler()->isGood()) { 31393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kOpenOutput; 31493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 31593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 31693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (mShared) { 31793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mLDInfo->output().setType(mcld::Output::DynObj); 31893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } else { 31993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mLDInfo->output().setType(mcld::Output::Exec); 32093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 32193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 32293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mLDInfo->output().setSOName(mSOName); 32393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mLDInfo->output().setMemArea(out_area); 32493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mLDInfo->output().setContext(mLDInfo->contextFactory().produce(pPath)); 32593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 32693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // FIXME: We must initialize MCLinker before setOutput, and initialize 32793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // standard sections here. This is because we have to build the section 32893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // map before input files using it. 32993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (!mDriver->hasInitLinker()) { 33093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kNotConfig; 33193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 33293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 33393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->initStdSections(); 33493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 33593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kSuccess; 33693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 33793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 33893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::setOutput(int pFileHandler) { 33993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (mLDInfo->output().hasContext()) { 34093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kDoubleConfig; 34193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 34293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 34393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // ----- initialize output file ----- // 34493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mcld::MemoryArea* out_area = mMemAreaFactory->produce(pFileHandler); 34593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 34693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mLDInfo->output().setType(mcld::Output::DynObj); 34793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mLDInfo->output().setMemArea(out_area); 34893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mLDInfo->output().setContext(mLDInfo->contextFactory().produce()); 34993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 35093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // FIXME: We must initialize MCLinker before setOutput, and initialize 35193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // standard sections here. This is because we have to build the section 35293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao // map before input files using it. 35393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (!mDriver->hasInitLinker()) { 35493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kNotConfig; 35593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 35693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 35793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->initStdSections(); 35893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 35993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kSuccess; 36093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 36193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 36293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liaoenum Linker::ErrorCode Linker::link() { 36393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->normalize(); 36493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 36503547495b607bb2293a884c0335fe234de49e1ddShih-wei Liao if (!mDriver->mergeSections()) { 36693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kReadSections; 36793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 36893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 36993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao if (!mDriver->addStandardSymbols() || !mDriver->addTargetSymbols()) { 37093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kAddAdditionalSymbols; 37193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao } 37293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 37393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->readRelocations(); 37493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->prelayout(); 37593c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->layout(); 37693c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->postlayout(); 37793c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->finalizeSymbolValue(); 37893c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->relocation(); 37993c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->emitOutput(); 38093c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao mDriver->postProcessing(); 38193c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 38293c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao return kSuccess; 38393c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao} 38493c8832a6916a54d984764bf83a8a77cbae4143bShih-wei Liao 385