167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//===- TestLinker.cpp -----------------------------------------------------===//
267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//
367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//                     The MCLinker Project
467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//
567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao// This file is distributed under the University of Illinois Open Source
667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao// License. See LICENSE.TXT for details.
767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//
867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//===----------------------------------------------------------------------===//
967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include "TestLinker.h"
1067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
1167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <iostream>
1267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
1367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <llvm/Support/TargetSelect.h>
1467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
1567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/LD/TextDiagnosticPrinter.h>
1667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/MC/InputTree.h>
17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/MC/MCLDDirectory.h>
1867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/Target/TargetLDBackend.h>
1967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/Support/RegionFactory.h>
2067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/Support/TargetSelect.h>
2167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/Support/MsgHandling.h>
2267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/Support/raw_ostream.h>
2367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/Support/SystemUtils.h>
24cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Support/MemoryAreaFactory.h>
2567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
2667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaousing namespace std;
2767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaousing namespace mcld;
28cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaousing namespace mcld::sys::fs;
2967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaousing namespace mcld::test;
3067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
3167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//===----------------------------------------------------------------------===//
3267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao// TestLinker
3367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//===----------------------------------------------------------------------===//
3467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei LiaoTestLinker::TestLinker()
3567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  : m_pTarget(NULL), m_pDriver(NULL), m_pInfo(NULL), m_pDiagLineInfo(NULL),
36cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    m_pDiagPrinter(NULL), m_pBackend(NULL), m_pRegionFactory(NULL),
37cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    m_pMemAreaFactory(NULL) {
3867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
3967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
4067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei LiaoTestLinker::~TestLinker()
4167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
4267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  std::list<mcld::FileHandle*>::iterator file, fEnd = m_FileHandleList.end();
4367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  for (file = m_FileHandleList.begin(); file != fEnd; ++file)
4467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    delete (*file);
4567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
4667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  std::list<mcld::MemoryArea*>::iterator mem, mEnd = m_MemAreaList.end() ;
4767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  for (mem = m_MemAreaList.begin(); mem != mEnd; ++mem)
4867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    delete (*mem);
4967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
5067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  delete m_pDriver;
5167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  delete m_pInfo;
5267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  delete m_pDiagLineInfo;
5367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  delete m_pDiagPrinter;
5467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  delete m_pBackend;
5567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  delete m_pRegionFactory;
56cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  delete m_pMemAreaFactory;
5767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
5867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
5967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaobool TestLinker::initialize(const std::string &pTriple)
6067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
6167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  bool is_initialized = false;
6267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
6367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (is_initialized)
6467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    return false;
6567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
6667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  // initilaize all llvm::Target and mcld::Target
6767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  llvm::InitializeAllTargets();
6867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  llvm::InitializeAllAsmPrinters();
6967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  llvm::InitializeAllAsmParsers();
7067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  llvm::InitializeAllTargetMCs();
7167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::InitializeAllTargets();
7267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::InitializeAllDiagnostics();
7367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
7467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  // create mcld::MCLDInfo
7567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pInfo = new MCLDInfo(pTriple, 1, 32);
7667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_Root = m_pInfo->inputs().root();
7767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
7867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  // create mcld::RegionFactory
7967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pRegionFactory = new mcld::RegionFactory(32);
8067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
8167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  // specify mcld::Target
8267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  std::string error;
8367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pTarget = mcld::TargetRegistry::lookupTarget(pTriple, error);
8467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (NULL == m_pTarget) {
8567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    fatal(diag::fatal_cannot_init_target) << pTriple << error;
8667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    return false;
8767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  }
8867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
8967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  // create mcld::DiagnosticEngine
9067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pDiagLineInfo = m_pTarget->createDiagnosticLineInfo(*m_pTarget, pTriple);
9167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (NULL == m_pDiagLineInfo) {
9267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    fatal(diag::fatal_cannot_init_lineinfo) << pTriple;
9367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    return false;
9467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  }
9567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
9667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pDiagPrinter = new mcld::TextDiagnosticPrinter(mcld::errs(), *m_pInfo);
9767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
9867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::InitializeDiagnosticEngine(*m_pInfo, m_pDiagLineInfo, m_pDiagPrinter);
9967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
10067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  // create mcld::TargetLDBackend
10167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pBackend = m_pTarget->createLDBackend(pTriple);
10267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (NULL == m_pBackend) {
10367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    fatal(diag::fatal_cannot_init_backend) << pTriple;
10467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    return false;
10567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  }
10667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
107cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  m_pMemAreaFactory = new MemoryAreaFactory(32);
10867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
109cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  m_pDriver = new mcld::MCLDDriver(*m_pInfo, *m_pBackend, *m_pMemAreaFactory);
11067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pDriver->initMCLinker();
11167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
11267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  is_initialized = true;
11367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  return true;
11467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
11567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
116cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaovoid TestLinker::addSearchDir(const std::string &pDirPath)
117cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
118cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  assert(NULL != m_pInfo && "initialize() must be called before addSearchDir");
119cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  assert(!m_pInfo->options().sysroot().empty() &&
120cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao         "must setSysRoot before addSearchDir");
121cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
122cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  mcld::MCLDDirectory* sd = new mcld::MCLDDirectory(pDirPath);
123cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
124cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (sd->isInSysroot()) {
125cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    sd->setSysroot(m_pInfo->options().sysroot());
126cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  }
127cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
128cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (exists(sd->path()) && is_directory(sd->path())) {
129cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    m_pInfo->options().directories().add(*sd);
130cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  } else {
131cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    mcld::warning(mcld::diag::warn_cannot_open_search_dir) << sd->name();
132cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  }
133cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
134cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
135cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaovoid TestLinker::setSysRoot(const mcld::sys::fs::Path &pPath)
136cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
137cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  assert(NULL != m_pInfo && "initialize() must be called before setSysRoot");
138cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  m_pInfo->options().setSysroot(pPath);
139cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
140cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
14167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaovoid TestLinker::addObject(const std::string &pPath)
14267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
14367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::Input* input = m_pInfo->inputFactory().produce(pPath, pPath,
14467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                       mcld::Input::Unknown);
14567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
14667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pInfo->inputs().insert<mcld::InputTree::Positional>(m_Root, *input);
14767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
14867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  advanceRoot();
14967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
15067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::FileHandle* handler = new mcld::FileHandle();
15167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_FileHandleList.push_back(handler);
15267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (!handler->open(pPath, mcld::FileHandle::ReadOnly)) {
15367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    mcld::error(mcld::diag::err_cannot_open_file)
15467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                      << pPath
15567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                      << mcld::sys::strerror(handler->error());
15667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  }
15767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
15867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::MemoryArea* input_memory = new MemoryArea(*m_pRegionFactory, *handler);
15967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  input->setMemArea(input_memory);
16067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_MemAreaList.push_back(input_memory);
16167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
16267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::LDContext* context = m_pInfo->contextFactory().produce(pPath);
16367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  input->setContext(context);
16467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
16567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
16667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaovoid TestLinker::addObject(void* pMemBuffer, size_t pSize)
16767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
16867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::Input* input = m_pInfo->inputFactory().produce("memory object", "NAN",
16967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                       mcld::Input::Unknown);
17067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
17167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pInfo->inputs().insert<mcld::InputTree::Positional>(m_Root, *input);
17267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
17367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  advanceRoot();
17467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
17567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::Space* space = new mcld::Space(mcld::Space::EXTERNAL, pMemBuffer, pSize);
17667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::MemoryArea* input_memory = new MemoryArea(*m_pRegionFactory, *space);
17767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  input->setMemArea(input_memory);
17867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_MemAreaList.push_back(input_memory);
17967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
18067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::LDContext* context = m_pInfo->contextFactory().produce();
18167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  input->setContext(context);
18267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
18367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
18467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaovoid TestLinker::addObject(int pFileHandler)
18567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
18667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::Input* input = m_pInfo->inputFactory().produce("handler object", "NAN",
18767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                       mcld::Input::Unknown);
18867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
18967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pInfo->inputs().insert<mcld::InputTree::Positional>(m_Root, *input);
19067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
19167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  advanceRoot();
19267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
19367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::FileHandle* handler = new mcld::FileHandle();
19467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_FileHandleList.push_back(handler);
19567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  handler->delegate(pFileHandler);
19667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
19767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::MemoryArea* input_memory = new MemoryArea(*m_pRegionFactory, *handler);
19867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  input->setMemArea(input_memory);
19967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_MemAreaList.push_back(input_memory);
20067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
20167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::LDContext* context = m_pInfo->contextFactory().produce();
20267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  input->setContext(context);
20367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
20467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
20567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaovoid TestLinker::addNameSpec(const std::string &pNameSpec)
20667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
20767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::sys::fs::Path* path = NULL;
20867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  // find out the real path of the namespec.
20967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (m_pInfo->attrFactory().constraint().isSharedSystem()) {
21067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    // In the system with shared object support, we can find both archive
21167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    // and shared object.
21267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
21367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    if (m_pInfo->attrFactory().last().isStatic()) {
21467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      // with --static, we must search an archive.
21567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      path = m_pInfo->options().directories().find(pNameSpec,
21667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                   mcld::Input::Archive);
21767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    }
21867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    else {
21967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      // otherwise, with --Bdynamic, we can find either an archive or a
22067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      // shared object.
22167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      path = m_pInfo->options().directories().find(pNameSpec,
22267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                   mcld::Input::DynObj);
22367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    }
22467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  }
22567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  else {
22667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    // In the system without shared object support, we only look for an
22767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    // archive.
22867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    path = m_pInfo->options().directories().find(pNameSpec,
22967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                 mcld::Input::Archive);
23067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  }
23167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
23267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (NULL == path) {
23367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    mcld::fatal(diag::err_cannot_find_namespec) << pNameSpec;
23467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    return;
23567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  }
23667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
23767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::Input* input = m_pInfo->inputFactory().produce(pNameSpec, *path,
23867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                       mcld::Input::Unknown);
23967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
24067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pInfo->inputs().insert<mcld::InputTree::Positional>(m_Root, *input);
24167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
24267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  advanceRoot();
24367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
24467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::FileHandle* handler = new mcld::FileHandle();
24567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_FileHandleList.push_back(handler);
24667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (!handler->open(*path, mcld::FileHandle::ReadOnly)) {
24767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    mcld::error(mcld::diag::err_cannot_open_file)
24867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                      << *path
24967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                      << mcld::sys::strerror(handler->error());
25067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  }
25167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
25267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::MemoryArea* input_memory = new MemoryArea(*m_pRegionFactory, *handler);
25367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  input->setMemArea(input_memory);
25467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_MemAreaList.push_back(input_memory);
25567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
25667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::LDContext* context = m_pInfo->contextFactory().produce(*path);
25767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  input->setContext(context);
25867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
25967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
26067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaobool TestLinker::setOutput(const std::string &pPath)
26167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
26267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (m_pInfo->output().hasContext())
26367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    return false;
26467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
26567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::FileHandle* handler = new mcld::FileHandle();
26667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_FileHandleList.push_back(handler);
26767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  bool open_res = handler->open(pPath, mcld::FileHandle::ReadWrite |
26867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                       mcld::FileHandle::Truncate |
26967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                       mcld::FileHandle::Create,
27067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                mcld::FileHandle::Permission(0755));
27167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (!open_res) {
27267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    mcld::error(mcld::diag::err_cannot_open_file)
27367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                      << pPath
27467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                      << mcld::sys::strerror(handler->error());
27567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  }
27667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
27767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::MemoryArea* output_memory = new MemoryArea(*m_pRegionFactory, *handler);
27867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pInfo->output().setMemArea(output_memory);
27967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_MemAreaList.push_back(output_memory);
28067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
28167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::LDContext* context = m_pInfo->contextFactory().produce(pPath);
28267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pInfo->output().setContext(context);
28367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
28467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  // FIXME: remove the initStdSections().
28567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pDriver->initStdSections();
28667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  return true;
28767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
28867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
289cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool TestLinker::setOutput(const sys::fs::Path &pPath)
290cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
291cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return setOutput(pPath.native());
292cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
293cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
29467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaobool TestLinker::setOutput(int pFileHandler)
29567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
29667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  if (m_pInfo->output().hasContext())
29767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    return false;
29867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
29967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::FileHandle* handler = new mcld::FileHandle();
30067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  handler->delegate(pFileHandler);
30167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_FileHandleList.push_back(handler);
30267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
30367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::MemoryArea* output_memory = new MemoryArea(*m_pRegionFactory, *handler);
30467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pInfo->output().setMemArea(output_memory);
30567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_MemAreaList.push_back(output_memory);
30667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
30767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::LDContext* context = m_pInfo->contextFactory().produce();
30867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pInfo->output().setContext(context);
30967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
31067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  // FIXME: remove the initStdSections().
31167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  m_pDriver->initStdSections();
31267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  return true;
31367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
31467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
31567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaovoid TestLinker::advanceRoot()
31667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
31767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    if (m_Root.isRoot())
31867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      --m_Root;
31967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    else
32067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      ++m_Root;
32167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
322