1affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===- Linker.cpp ---------------------------------------------------------===// 2affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 3affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// The MCLinker Project 4affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 5affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This file is distributed under the University of Illinois Open Source 6affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// License. See LICENSE.TXT for details. 7affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 8affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 10affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include "alone/Linker.h" 11affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include "alone/Support/LinkerConfig.h" 12affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include "alone/Support/MemoryFactory.h" 1367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include "alone/Support/Log.h" 14affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/ELF.h> 16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/MC/MCLDDriver.h> 1867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/MC/InputTree.h> 19affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/MCLinker.h> 20affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/InputTree.h> 21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/LDSection.h> 22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/LDContext.h> 23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Target/TargetLDBackend.h> 24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/Path.h> 25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryArea.h> 26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/FileHandle.h> 2767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/Support/MemoryAreaFactory.h> 2867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/Support/TargetRegistry.h> 29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 30affc150dc44fab1911775a49636d0ce85333b634Zonr Changusing namespace alone; 31affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoconst char* Linker::GetErrorString(enum Linker::ErrorCode pErrCode) { 33affc150dc44fab1911775a49636d0ce85333b634Zonr Chang static const char* ErrorString[] = { 34affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kSuccess */ 35affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Successfully compiled.", 36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kDoubleConfig */ 37affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Configure Linker twice.", 38affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kCreateBackend */ 39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Cannot create backend.", 40affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kDelegateLDInfo */ 41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Cannot get linker information", 4267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao /* kFindNameSpec */ 4367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao "Cannot find -lnamespec", 44affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kOpenNameSpec */ 45affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Cannot open -lnamespec", 46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kOpenObjectFile */ 47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Cannot open object file", 48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kNotConfig */ 49affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Linker::config() is not called", 50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kNotSetUpOutput */ 51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Linker::setOutput() is not called before add input files", 52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kOpenOutput */ 53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Cannot open output file", 54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kReadSections */ 55affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Cannot read sections", 56affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kReadSymbols */ 57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Cannot read symbols", 58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kAddAdditionalSymbols */ 59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "Cannot add standard and target symbols", 60affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /* kMaxErrorCode */ 61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "(Unknown error code)" 62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang }; 63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 64affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pErrCode > kMaxErrorCode) { 65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pErrCode = kMaxErrorCode; 66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return ErrorString[ static_cast<size_t>(pErrCode) ]; 69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Linker 73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 74affc150dc44fab1911775a49636d0ce85333b634Zonr ChangLinker::Linker() 7567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL), 7667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mRoot(NULL), mShared(false) { 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 79affc150dc44fab1911775a49636d0ce85333b634Zonr ChangLinker::Linker(const LinkerConfig& pConfig) 8067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL), 8167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mRoot(NULL), mShared(false) { 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const std::string &triple = pConfig.getTriple(); 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang enum ErrorCode err = config(pConfig); 86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (kSuccess != err) { 87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ALOGE("%s (%s)", GetErrorString(err), triple.c_str()); 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 9467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei LiaoLinker::~Linker() { 9567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao delete mDriver; 9667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao delete mBackend; 9767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao delete mMemAreaFactory; 98cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao delete mRoot; 99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 10167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig) { 102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mLDInfo = const_cast<mcld::MCLDInfo*>(pConfig.getLDInfo()); 10367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (mLDInfo == NULL) { 104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kDelegateLDInfo; 10567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 10667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 107cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao mRoot = new mcld::InputTree::iterator(mLDInfo->inputs().root()); 10867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mShared = pConfig.isShared(); 10967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mSOName = pConfig.getSOName(); 110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kSuccess; 112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 11467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::config(const LinkerConfig& pConfig) { 11567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (mLDInfo != NULL) { 116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kDoubleConfig; 11767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang extractFiles(pConfig); 120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mBackend = pConfig.getTarget()->createLDBackend(pConfig.getTriple()); 12267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (mBackend == NULL) { 123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kCreateBackend; 12467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mMemAreaFactory = new MemoryFactory(); 127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 128cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao mDriver = new mcld::MCLDDriver(*mLDInfo, *mBackend, *mMemAreaFactory); 129cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->initMCLinker(); 131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kSuccess; 133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 13567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaovoid Linker::advanceRoot() { 13667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (mRoot->isRoot()) { 13767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mRoot->move<mcld::TreeIteratorBase::Leftward>(); 13867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } else { 13967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mRoot->move<mcld::TreeIteratorBase::Rightward>(); 14067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 14167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 14467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::openFile(const mcld::sys::fs::Path& pPath, 14567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao enum Linker::ErrorCode pCode, 14667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::Input& pInput) { 147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pPath, 148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::FileHandle::ReadOnly); 149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (input_memory->handler()->isGood()) { 151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pInput.setMemArea(input_memory); 15267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } else { 153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return pCode; 15467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::LDContext *input_context = mLDInfo->contextFactory().produce(pPath); 157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pInput.setContext(input_context); 158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kSuccess; 159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 16167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec) { 162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::sys::fs::Path* path = NULL; 163affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // find out the real path of the namespec. 164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (mLDInfo->attrFactory().constraint().isSharedSystem()) { 165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // In the system with shared object support, we can find both archive 166affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // and shared object. 167affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (mLDInfo->attrFactory().last().isStatic()) { 169affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // with --static, we must search an archive. 17067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao path = mLDInfo->options().directories().find(pNameSpec, 17167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::Input::Archive); 172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 173affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 174affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // otherwise, with --Bdynamic, we can find either an archive or a 175affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // shared object. 17667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao path = mLDInfo->options().directories().find(pNameSpec, 17767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::Input::DynObj); 178affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 179affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // In the system without shared object support, we only look for an 182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // archive. 18367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao path = mLDInfo->options().directories().find(pNameSpec, 18467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::Input::Archive); 185affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 18767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (NULL == path) 18867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return kFindNameSpec; 18967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::Input* input = mLDInfo->inputFactory().produce(pNameSpec, *path, 19167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::Input::Unknown); 19267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input); 193affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang advanceRoot(); 195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return openFile(*path, kOpenNameSpec, *input); 197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// addObject - Add a object file by the filename. 20067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath) { 201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::Input* input = mLDInfo->inputFactory().produce(pObjectPath, 202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pObjectPath, 203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::Input::Unknown); 204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 20567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input); 206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang advanceRoot(); 208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return openFile(pObjectPath, kOpenObjectFile, *input); 210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// addObject - Add a piece of memory. The memory is of ELF format. 21367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize) { 214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::Input* input = mLDInfo->inputFactory().produce("memory object", 216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "NAN", 217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::Input::Unknown); 218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 21967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input); 220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang advanceRoot(); 222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize); 224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang input->setMemArea(input_memory); 225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::LDContext *input_context = mLDInfo->contextFactory().produce(); 227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang input->setContext(input_context); 228affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kSuccess; 230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 23267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize) { 233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::Input* input = mLDInfo->inputFactory().produce("code object", 23467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao "NAN", 23567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::Input::External); 236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 23767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input); 238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang advanceRoot(); 240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize); 242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang input->setMemArea(input_memory); 243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::LDContext *input_context = mLDInfo->contextFactory().produce(); 245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang input->setContext(input_context); 246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: So far, MCLinker must set up output before add input files. 248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // set up LDContext 24967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (mDriver->hasInitLinker()) { 250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kNotConfig; 25167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 25367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (!mLDInfo->output().hasContext()) { 254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kNotSetUpOutput; 25567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 256affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 257affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // create NULL section 25867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::LDSection& null = 25967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mDriver->getLinker()->createSectHdr("", 26067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::LDFileFormat::Null, 26167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao llvm::ELF::SHT_NULL, 26267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 0); 263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang null.setSize(0); 265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang null.setOffset(0); 266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang null.setIndex(0); 267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang null.setInfo(0); 268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang null.setAlign(0); 269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang input_context->getSectionTable().push_back(&null); 271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // create .text section 273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::LDSection& text = mDriver->getLinker()->createSectHdr(".text", 274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::LDFileFormat::Regular, 275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHT_PROGBITS, 276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR); 277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang text.setSize(pSize); 279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang text.setOffset(0x0); 280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang text.setIndex(1); 281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang text.setInfo(0); 282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang text.setAlign(1); 283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang input_context->getSectionTable().push_back(&text); 285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kSuccess; 287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 28967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::setOutput(const std::string &pPath) { 29067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (mLDInfo->output().hasContext()) { 291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kDoubleConfig; 29267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- initialize output file ----- // 295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::FileHandle::Permission perm = 0755; 297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::MemoryArea* out_area = mMemAreaFactory->produce( 29967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao pPath, 30067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::FileHandle::ReadWrite | 30167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::FileHandle::Truncate | 30267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mcld::FileHandle::Create, 30367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao perm); 304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 30567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (!out_area->handler()->isGood()) { 306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kOpenOutput; 30767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 30967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (mShared) { 31067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mLDInfo->output().setType(mcld::Output::DynObj); 31167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } else { 31267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mLDInfo->output().setType(mcld::Output::Exec); 31367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 31467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 31567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao mLDInfo->output().setSOName(mSOName); 316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mLDInfo->output().setMemArea(out_area); 317affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mLDInfo->output().setContext(mLDInfo->contextFactory().produce(pPath)); 318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: We must initialize MCLinker before setOutput, and initialize 320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // standard sections here. This is because we have to build the section 321affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // map before input files using it. 32267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (!mDriver->hasInitLinker()) { 323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kNotConfig; 32467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 326affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->initStdSections(); 327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kSuccess; 329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 33167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::setOutput(int pFileHandler) { 33267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (mLDInfo->output().hasContext()) { 333affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kDoubleConfig; 33467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 335affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 336affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- initialize output file ----- // 337affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mcld::MemoryArea* out_area = mMemAreaFactory->produce(pFileHandler); 338affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 339affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mLDInfo->output().setType(mcld::Output::DynObj); 340affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mLDInfo->output().setMemArea(out_area); 341affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mLDInfo->output().setContext(mLDInfo->contextFactory().produce()); 342affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: We must initialize MCLinker before setOutput, and initialize 344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // standard sections here. This is because we have to build the section 345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // map before input files using it. 34667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (!mDriver->hasInitLinker()) { 347affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kNotConfig; 34867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 34967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->initStdSections(); 351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kSuccess; 353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 35567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaoenum Linker::ErrorCode Linker::link() { 356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->normalize(); 357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 358cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (!mDriver->mergeSections()) { 359affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kReadSections; 36067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 36267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao if (!mDriver->addStandardSymbols() || !mDriver->addTargetSymbols()) { 363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kAddAdditionalSymbols; 36467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 365affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->readRelocations(); 367affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->prelayout(); 368affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->layout(); 369affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->postlayout(); 370affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->finalizeSymbolValue(); 371affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->relocation(); 372affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->emitOutput(); 373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang mDriver->postProcessing(); 374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return kSuccess; 376affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 377affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 378