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; }
// 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 TargetControlOptions::parse(LinkerConfig& pConfig) { // set -G [size] pConfig.options().setGPSize(m_GPSize); // set --warn-shared-textrel pConfig.options().setWarnSharedTextrel(m_WarnSharedTextrel); // set --fix-cortex-a8 if (m_FIXCA8) mcld::warning(mcld::diag::warn_unsupported_option) << m_FIXCA8.ArgStr; return true; }
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 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; }
//===----------------------------------------------------------------------===// // Testcases //===----------------------------------------------------------------------===// TEST_F(ELFBinaryReaderTest, is_myformat) { LinkerScript script; Module module("test", script); LinkerConfig config; IRBuilder builder(module, config); ELFBinaryReader* reader = new ELFBinaryReader(builder, config); Input input("test.bin"); bool doContinue = false; config.options().setBinaryInput(); ASSERT_TRUE(reader->isMyFormat(input, doContinue)); config.options().setBinaryInput(false); ASSERT_FALSE(reader->isMyFormat(input, doContinue)); delete reader; }
/// getEntryPoint uint64_t ELFObjectWriter::getEntryPoint(const LinkerConfig& pConfig, const Module& pModule) const { llvm::StringRef entry_name; if (pConfig.options().hasEntry()) entry_name = pConfig.options().entry(); else entry_name = target().getInfo().entry(); uint64_t result = 0x0; bool issue_warning = (pConfig.options().hasEntry() && LinkerConfig::Object != pConfig.codeGenType() && LinkerConfig::DynObj != pConfig.codeGenType()); const LDSymbol* entry_symbol = pModule.getNamePool().findSymbol(entry_name); // found the symbol if (NULL != entry_symbol) { if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) { llvm::errs() << "WARNING: entry symbol '" << entry_symbol->name() << "' exists but is not defined.\n"; } result = entry_symbol->value(); } // not in the symbol pool else { // We should parse entry as a number. // @ref GNU ld manual, Options -e. e.g., -e 0x1000. char* endptr; result = strtoull(entry_name.data(), &endptr, 0); if (*endptr != '\0') { if (issue_warning) { llvm::errs() << "cannot find entry symbol '" << entry_name.data() << "'.\n"; } result = 0x0; } } return result; }
bool OptimizationOptions::parse(LinkerConfig& pConfig) { // set --gc-sections if (m_GCSections) pConfig.options().setGCSections(); // set --ld-generated-unwind-info (or not) pConfig.options().setGenUnwindInfo(m_GenUnwindInfo); // set --icf [mode] switch (m_ICF) { case ICF_None: break; case ICF_All: case ICF_Safe: default: warning(mcld::diag::warn_unsupported_option) << m_ICF.ArgStr; break; } return true; }
bool OutputFormatOptions::parse(mcld::Module& pModule, LinkerConfig& pConfig) { if (!parseOutput(pModule, pConfig)) { mcld::unreachable(mcld::diag::unrecognized_output_file) << pModule.name(); return false; } if (mcld::Input::Binary == m_Format) pConfig.options().setBinaryInput(); pConfig.options().setStripDebug(m_StripDebug || m_StripAll); if (m_StripAll) pConfig.options().setStripSymbols(mcld::GeneralOptions::StripAllSymbols); else if (m_DiscardAll) pConfig.options().setStripSymbols(mcld::GeneralOptions::StripLocals); else if (m_DiscardLocals) pConfig.options().setStripSymbols(mcld::GeneralOptions::StripTemporaries); else pConfig.options().setStripSymbols(mcld::GeneralOptions::KeepAllSymbols); pConfig.options().setEhFrameHdr(m_EhFrameHdr); pConfig.options().setPIE(m_PIE); pConfig.options().setNMagic(m_NMagic); pConfig.options().setOMagic(m_OMagic); pConfig.options().setHashStyle(m_HashStyle); pConfig.options().setExportDynamic(m_ExportDynamic); if (m_NoWarnMismatch) pConfig.options().setWarnMismatch(false); else pConfig.options().setWarnMismatch(true); // build-id // exclude-libs return true; }