int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); { ErrorOr<std::unique_ptr<MemoryBuffer>> mb = MemoryBuffer::getFileOrSTDIN(argv[1]); if (std::error_code ec = mb.getError()) { llvm::errs() << ec.message() << "\n"; return 1; } Lexer l(std::move(mb.get())); Token tok; while (true) { l.lex(tok); tok.dump(llvm::outs()); if (tok._kind == Token::eof || tok._kind == Token::unknown) break; } } { ErrorOr<std::unique_ptr<MemoryBuffer>> mb = MemoryBuffer::getFileOrSTDIN(argv[1]); if (std::error_code ec = mb.getError()) { llvm::errs() << ec.message() << "\n"; return 1; } Parser p(std::move(mb.get())); if (!p.parse()) { LinkerScript *ls = p.get(); ls->dump(llvm::outs()); } } }
static bool MCLDEmulateARMELF(LinkerScript& pScript, LinkerConfig& pConfig) { if (!MCLDEmulateELF(pScript, pConfig)) return false; // set up bitclass and endian pConfig.targets().setEndian(TargetOptions::Little); pConfig.targets().setBitClass(32); // set up target-dependent constraints of attributes pConfig.attribute().constraint().enableWholeArchive(); pConfig.attribute().constraint().enableAsNeeded(); pConfig.attribute().constraint().setSharedSystem(); // set up the predefined attributes pConfig.attribute().predefined().unsetWholeArchive(); pConfig.attribute().predefined().unsetAsNeeded(); pConfig.attribute().predefined().setDynamic(); // set up section map if (pConfig.options().getScriptList().empty() && pConfig.codeGenType() != LinkerConfig::Object) { pScript.sectionMap().insert(".ARM.exidx*", ".ARM.exidx"); pScript.sectionMap().insert(".ARM.extab*", ".ARM.extab"); pScript.sectionMap().insert(".ARM.attributes*", ".ARM.attributes"); } 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; }
// %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(); }
// 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 DynamicSectionOptions::parse(LinkerConfig& pConfig, LinkerScript& pScript) { // set up entry point from -e pScript.setEntry(m_Entry); // --Bsymbolic pConfig.options().setBsymbolic(m_Bsymbolic); // --Bgroup pConfig.options().setBgroup(m_Bgroup); // set --soname [soname] pConfig.options().setSOName(m_SOName); // set -z options llvm::cl::list<ZOption>::iterator zOpt; llvm::cl::list<ZOption>::iterator zOptEnd = m_ZOptionList.end(); for (zOpt = m_ZOptionList.begin(); zOpt != zOptEnd; ++zOpt) { pConfig.options().addZOption(*zOpt); } // set --no-undefined if (llvm::cl::BOU_UNSET != m_NoUndefined) pConfig.options().setNoUndefined(llvm::cl::BOU_TRUE == m_NoUndefined); // set --allow-multiple-definition if (llvm::cl::BOU_UNSET != m_AllowMulDefs) pConfig.options().setMulDefs(llvm::cl::BOU_TRUE == m_AllowMulDefs); // set --dynamic-linker [dyld] pConfig.options().setDyld(m_Dyld); // set --enable-new-dtags pConfig.options().setNewDTags(m_EnableNewDTags); // set --auxiliary, -f llvm::cl::list<std::string>::iterator aux; llvm::cl::list<std::string>::iterator auxEnd = m_Auxiliary.end(); for (aux = m_Auxiliary.begin(); aux != auxEnd; ++aux) pConfig.options().getAuxiliaryList().push_back(*aux); // set --filter, -F pConfig.options().setFilter(m_Filter); return true; }
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; }