// FIXME: LinkerConfig& pConfig should be constant
bool MCLDEmulateELF(LinkerScript& pScript, LinkerConfig& pConfig) {
  // set up section map
  if (pConfig.options().getScriptList().empty() &&
      pConfig.codeGenType() != LinkerConfig::Object) {
    const unsigned int map_size = (sizeof(map) / sizeof(map[0]));
    for (unsigned int i = 0; i < map_size; ++i) {
      std::pair<SectionMap::mapping, bool> res =
          pScript.sectionMap().insert(map[i].from, map[i].to, map[i].policy);
      if (!res.second)
        return false;
    }
  } else {
    // FIXME: this is the hack to help assignment processing in current
    // implementation.
    pScript.sectionMap().insert("", "");
  }

  if (!pConfig.options().nostdlib()) {
    // TODO: check if user sets the default search path instead via -Y option
    // set up default search path
    switch (pConfig.targets().triple().getOS()) {
      case llvm::Triple::NetBSD:
        pScript.directories().insert("=/usr/lib");
        break;
      case llvm::Triple::Win32:
        pScript.directories().insert("=/mingw/lib");
        break;
      default:
        pScript.directories().insert("=/lib");
        pScript.directories().insert("=/usr/lib");
        break;
    }
  }
  return true;
}
bool SearchPathOptions::parse(LinkerConfig& pConfig, LinkerScript& pScript)
{
  // set --sysroot
  if (!m_SysRoot.empty()) {
    if (exists(m_SysRoot) && is_directory(m_SysRoot))
      pScript.setSysroot(m_SysRoot);
  }

  // set -L[path]
  llvm::cl::list<std::string>::iterator sd;
  llvm::cl::list<std::string>::iterator sdEnd = m_SearchDirList.end();
  for (sd = m_SearchDirList.begin(); sd != sdEnd; ++sd) {
    if (!pScript.directories().insert(*sd)) {
      // FIXME: need a warning function
      errs() << "WARNING: can not open search directory `-L"
             << *sd
             << "'.\n";
    }
  }

  // set -no-stdlib
  pConfig.options().setNoStdlib(m_NoStdlib);

  // set --rpath [path]
  llvm::cl::list<std::string>::iterator rp;
  llvm::cl::list<std::string>::iterator rpEnd = m_RuntimePath.end();
  for (rp = m_RuntimePath.begin(); rp != rpEnd; ++rp) {
    pConfig.options().getRpathList().push_back(*rp);
  }

  return true;
}
예제 #3
0
// %MCLinker --shared -soname=libplasma.so -Bsymbolic
// -mtriple="armv7-none-linux-gnueabi"
// -L=%p/../../../libs/ARM/Android/android-14
// %p/../../../libs/ARM/Android/android-14/crtbegin_so.o
// %p/plasma.o
// -lm -llog -ljnigraphics -lc
// %p/../../../libs/ARM/Android/android-14/crtend_so.o
// -o libplasma.so
TEST_F( LinkerTest, plasma) {

    Initialize();
    Linker linker;
    LinkerScript script;

    ///< --mtriple="armv7-none-linux-gnueabi"
    LinkerConfig config("armv7-none-linux-gnueabi");

    /// -L=${TOPDIR}/test/libs/ARM/Android/android-14
    Path search_dir(TOPDIR);
    search_dir.append("test/libs/ARM/Android/android-14");
    script.directories().insert(search_dir);

    /// To configure linker before setting options. Linker::config sets up
    /// default target-dependent configuration to LinkerConfig.
    linker.emulate(script, config);

    config.setCodeGenType(LinkerConfig::DynObj);  ///< --shared
    config.options().setSOName("libplasma.so");   ///< --soname=libplasma.so
    config.options().setBsymbolic();              ///< -Bsymbolic

    Module module("libplasma.so", script);
    IRBuilder builder(module, config);

    /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtbegin_so.o
    Path crtbegin(search_dir);
    crtbegin.append("crtbegin_so.o");
    builder.ReadInput("crtbegin", crtbegin);

    /// ${TOPDIR}/test/Android/Plasma/ARM/plasma.o
    Path plasma(TOPDIR);
    plasma.append("test/Android/Plasma/ARM/plasma.o");
    builder.ReadInput("plasma", plasma);

    // -lm -llog -ljnigraphics -lc
    builder.ReadInput("m");
    builder.ReadInput("log");
    builder.ReadInput("jnigraphics");
    builder.ReadInput("c");

    /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtend_so.o
    Path crtend(search_dir);
    crtend.append("crtend_so.o");
    builder.ReadInput("crtend", crtend);

    if (linker.link(module, builder)) {
        linker.emit("libplasma.so"); ///< -o libplasma.so
    }

    Finalize();
}
예제 #4
0
bool PositionalOptions::parse(std::vector<InputAction*>& pActions,
                              const LinkerConfig& pConfig,
                              const LinkerScript& pScript)
{
  if (0 == numOfInputs()) {
    fatal(diag::err_no_inputs);
    return false;
  }

  pActions.reserve(numOfActions());

  // -T/--script
  // FIXME:
  llvm::cl::list<std::string>::iterator sp;
  llvm::cl::list<std::string>::iterator spEnd = m_LinkerScript.end();
  for (sp = m_LinkerScript.begin(); sp != spEnd; ++sp) {
    pActions.push_back(new ScriptAction(0x0,
                                       *sp,
                                       ScriptFile::LDScript,
                                       pScript.directories()));
    pActions.push_back(new ContextAction(0x0));
    pActions.push_back(new MemoryAreaAction(0x0, FileHandle::ReadOnly));
  }

  // --defsym
  llvm::cl::list<std::string>::iterator defsym, dsBegin, dsEnd;
  dsBegin = m_DefSymList.begin();
  dsEnd = m_DefSymList.end();
  for (defsym = dsBegin; defsym != dsEnd; ++defsym) {
    unsigned int pos = m_DefSymList.getPosition(defsym - dsBegin);
    pActions.push_back(new DefSymAction(pos, *defsym));
  }

  // set input
  llvm::cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd;
  inBegin = m_InputObjectFiles.begin();
  inEnd = m_InputObjectFiles.end();
  for (input = inBegin; input != inEnd; ++input) {
    unsigned int pos = m_InputObjectFiles.getPosition(input - inBegin);
    pActions.push_back(new InputFileAction(pos, *input));
    pActions.push_back(new ContextAction(pos));
    pActions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
  }

  // set -l[namespec]
  llvm::cl::list<std::string>::iterator namespec, nsBegin, nsEnd;
  nsBegin = m_NameSpecList.begin();
  nsEnd = m_NameSpecList.end();
  for (namespec = nsBegin; namespec != nsEnd; ++namespec) {
    unsigned int pos = m_NameSpecList.getPosition(namespec - nsBegin);
    pActions.push_back(new NamespecAction(pos, *namespec,
                                          pScript.directories()));
    pActions.push_back(new ContextAction(pos));
    pActions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
  }

  // set --whole-archive
  llvm::cl::list<bool>::iterator attr, attrBegin, attrEnd;
  attrBegin = m_WholeArchiveList.begin();
  attrEnd   = m_WholeArchiveList.end();
  for (attr = attrBegin; attr != attrEnd; ++attr) {
    unsigned int pos = m_WholeArchiveList.getPosition(attr - attrBegin);
    pActions.push_back(new WholeArchiveAction(pos));
  }

  // set --no-whole-archive
  attrBegin = m_NoWholeArchiveList.begin();
  attrEnd   = m_NoWholeArchiveList.end();
  for (attr = attrBegin; attr != attrEnd; ++attr) {
    unsigned int pos = m_NoWholeArchiveList.getPosition(attr - attrBegin);
    pActions.push_back(new NoWholeArchiveAction(pos));
  }

  // set --as-needed
  attrBegin = m_AsNeededList.begin();
  attrEnd   = m_AsNeededList.end();
  for (attr = attrBegin; attr != attrEnd; ++attr) {
    unsigned int pos = m_AsNeededList.getPosition(attr - attrBegin);
    pActions.push_back(new AsNeededAction(pos));
  }

  // set --no-as-needed
  attrBegin = m_NoAsNeededList.begin();
  attrEnd   = m_NoAsNeededList.end();
  for (attr = attrBegin; attr != attrEnd; ++attr) {
    unsigned int pos = m_NoAsNeededList.getPosition(attr - attrBegin);
    pActions.push_back(new NoAsNeededAction(pos));
  }

  // set --add--needed
  attrBegin = m_AddNeededList.begin();
  attrEnd   = m_AddNeededList.end();
  for (attr = attrBegin; attr != attrEnd; ++attr) {
    unsigned int pos = m_AddNeededList.getPosition(attr - attrBegin);
    pActions.push_back(new AddNeededAction(pos));
  }

  // set --no-add--needed
  attrBegin = m_NoAddNeededList.begin();
  attrEnd   = m_NoAddNeededList.end();
  for (attr = attrBegin; attr != attrEnd; ++attr) {
    unsigned int pos = m_NoAddNeededList.getPosition(attr - attrBegin);
    pActions.push_back(new NoAddNeededAction(pos));
  }

  // set --Bdynamic
  attrBegin = m_BDynamicList.begin();
  attrEnd   = m_BDynamicList.end();
  for (attr = attrBegin; attr != attrEnd; ++attr) {
    unsigned int pos = m_BDynamicList.getPosition(attr - attrBegin);
    pActions.push_back(new BDynamicAction(pos));
  }

  // set --Bstatic
  attrBegin = m_BStaticList.begin();
  attrEnd   = m_BStaticList.end();
  for (attr = attrBegin; attr != attrEnd; ++attr) {
    unsigned int pos = m_BStaticList.getPosition(attr - attrBegin);
    pActions.push_back(new BStaticAction(pos));
  }

  // set --start-group
  llvm::cl::list<bool>::iterator group, gsBegin, gsEnd;
  gsBegin = m_StartGroupList.begin();
  gsEnd   = m_StartGroupList.end();
  for (group = gsBegin; group != gsEnd; ++group) {
    unsigned int pos = m_StartGroupList.getPosition(group - gsBegin);
    pActions.push_back(new StartGroupAction(pos));
  }

  // set --end-group
  gsBegin = m_EndGroupList.begin();
  gsEnd   = m_EndGroupList.end();
  for (group = gsBegin; group != gsEnd; ++group) {
    unsigned int pos = m_EndGroupList.getPosition(group - gsBegin);
    pActions.push_back(new EndGroupAction(pos));
  }

  // stable sort
  std::stable_sort(pActions.begin(), pActions.end(), CompareAction);

  return true;
}