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