137b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===- InputCmd.cpp -------------------------------------------------------===// 237b74a387bb3993387029859c2d9d051c41c724eStephen Hines// 337b74a387bb3993387029859c2d9d051c41c724eStephen Hines// The MCLinker Project 437b74a387bb3993387029859c2d9d051c41c724eStephen Hines// 537b74a387bb3993387029859c2d9d051c41c724eStephen Hines// This file is distributed under the University of Illinois Open Source 637b74a387bb3993387029859c2d9d051c41c724eStephen Hines// License. See LICENSE.TXT for details. 737b74a387bb3993387029859c2d9d051c41c724eStephen Hines// 837b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/InputCmd.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/Archive.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ArchiveReader.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/DynObjReader.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ObjectReader.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Attribute.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/InputBuilder.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/InputToken.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/StringList.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Path.h" 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/raw_ostream.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/InputTree.h" 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerScript.h" 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h" 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/Casting.h> 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <cassert> 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <iostream> 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===----------------------------------------------------------------------===// 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines// InputCmd 3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===----------------------------------------------------------------------===// 3737b74a387bb3993387029859c2d9d051c41c724eStephen HinesInputCmd::InputCmd(StringList& pStringList, 3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines InputTree& pInputTree, 3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines InputBuilder& pBuilder, 4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectReader& pObjectReader, 4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ArchiveReader& pArchiveReader, 4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines DynObjReader& pDynObjReader, 4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LinkerConfig& pConfig) 4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines : ScriptCommand(ScriptCommand::INPUT), 4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_StringList(pStringList), 4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_InputTree(pInputTree), 4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Builder(pBuilder), 4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ObjectReader(pObjectReader), 4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ArchiveReader(pArchiveReader), 5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_DynObjReader(pDynObjReader), 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Config(pConfig) { 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 5437b74a387bb3993387029859c2d9d051c41c724eStephen HinesInputCmd::~InputCmd() { 5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid InputCmd::dump() const { 5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::outs() << "INPUT ( "; 5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool prev = false, cur = false; 6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (StringList::const_iterator it = m_StringList.begin(), 6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ie = m_StringList.end(); 6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert((*it)->kind() == StrToken::Input); 6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines InputToken* input = llvm::cast<InputToken>(*it); 6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines cur = input->asNeeded(); 6737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!prev && cur) 6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::outs() << "AS_NEEDED ( "; 6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines else if (prev && !cur) 7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::outs() << " )"; 7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (input->type() == InputToken::NameSpec) 7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::outs() << "-l"; 7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::outs() << input->name() << " "; 7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines prev = cur; 7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!m_StringList.empty() && prev) 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::outs() << " )"; 8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::outs() << " )\n"; 8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid InputCmd::activate(Module& pModule) { 8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines LinkerScript& script = pModule.getScript(); 8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines // construct the INPUT tree 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Builder.setCurrentTree(m_InputTree); 8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool is_begin_marked = false; 9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines InputTree::iterator input_begin; 9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (StringList::const_iterator it = m_StringList.begin(), 9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ie = m_StringList.end(); 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert((*it)->kind() == StrToken::Input); 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines InputToken* token = llvm::cast<InputToken>(*it); 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (token->asNeeded()) 10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Builder.getAttributes().setAsNeeded(); 10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines else 10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Builder.getAttributes().unsetAsNeeded(); 10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (token->type()) { 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines case InputToken::File: { 10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines sys::fs::Path path; 10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines // 1. Looking for file in the sysroot prefix, if a sysroot prefix is 10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines // configured and the filename starts with '/' 11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (script.hasSysroot() && 11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines (token->name().size() > 0 && token->name()[0] == '/')) { 11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines path = script.sysroot(); 11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines path.append(token->name()); 11437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines // 2. Try to open the file in CWD 11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines path.assign(token->name()); 11737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!sys::fs::exists(path)) { 11837b74a387bb3993387029859c2d9d051c41c724eStephen Hines // 3. Search through the library search path 11937b74a387bb3993387029859c2d9d051c41c724eStephen Hines sys::fs::Path* p = 12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines script.directories().find(token->name(), Input::Script); 12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (p != NULL) 12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines path = *p; 12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 12437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!sys::fs::exists(path)) 12737b74a387bb3993387029859c2d9d051c41c724eStephen Hines fatal(diag::err_cannot_open_input) << path.filename() << path; 12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Builder.createNode<InputTree::Positional>( 13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines path.filename().native(), path, Input::Unknown); 13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines case InputToken::NameSpec: { 13437b74a387bb3993387029859c2d9d051c41c724eStephen Hines const sys::fs::Path* path = NULL; 13537b74a387bb3993387029859c2d9d051c41c724eStephen Hines // find out the real path of the namespec. 13637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_Builder.getConstraint().isSharedSystem()) { 13737b74a387bb3993387029859c2d9d051c41c724eStephen Hines // In the system with shared object support, we can find both archive 13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines // and shared object. 13937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_Builder.getAttributes().isStatic()) { 14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines // with --static, we must search an archive. 14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines path = script.directories().find(token->name(), Input::Archive); 14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 14337b74a387bb3993387029859c2d9d051c41c724eStephen Hines // otherwise, with --Bdynamic, we can find either an archive or a 14437b74a387bb3993387029859c2d9d051c41c724eStephen Hines // shared object. 14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines path = script.directories().find(token->name(), Input::DynObj); 14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 14737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 14837b74a387bb3993387029859c2d9d051c41c724eStephen Hines // In the system without shared object support, only look for an 14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines // archive 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines path = script.directories().find(token->name(), Input::Archive); 15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 15237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 15337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (path == NULL) 15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines fatal(diag::err_cannot_find_namespec) << token->name(); 15537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 15637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Builder.createNode<InputTree::Positional>( 15737b74a387bb3993387029859c2d9d051c41c724eStephen Hines token->name(), *path, Input::Unknown); 15837b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 15937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 16037b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 16137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(0 && "Invalid script token in INPUT!"); 16237b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 16337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 16437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 16537b74a387bb3993387029859c2d9d051c41c724eStephen Hines InputTree::iterator input = m_Builder.getCurrentNode(); 16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!is_begin_marked) { 16737b74a387bb3993387029859c2d9d051c41c724eStephen Hines input_begin = input; 16837b74a387bb3993387029859c2d9d051c41c724eStephen Hines is_begin_marked = true; 16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 17037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(*input != NULL); 17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!m_Builder.setMemory(**input, 17237b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileHandle::OpenMode(FileHandle::ReadOnly), 17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileHandle::Permission(FileHandle::System))) { 17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines error(diag::err_cannot_open_input) << (*input)->name() 17537b74a387bb3993387029859c2d9d051c41c724eStephen Hines << (*input)->path(); 17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 17737b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Builder.setContext(**input); 17837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 17937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 18037b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (InputTree::iterator input = input_begin, ie = m_InputTree.end(); 18137b74a387bb3993387029859c2d9d051c41c724eStephen Hines input != ie; 18237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++input) { 18337b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool doContinue = false; 18437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_ObjectReader.isMyFormat(**input, doContinue)) { 18537b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*input)->setType(Input::Object); 18637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ObjectReader.readHeader(**input); 18737b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ObjectReader.readSections(**input); 18837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ObjectReader.readSymbols(**input); 18937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pModule.getObjectList().push_back(*input); 19037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (doContinue && m_DynObjReader.isMyFormat(**input, doContinue)) { 19137b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*input)->setType(Input::DynObj); 19237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_DynObjReader.readHeader(**input); 19337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_DynObjReader.readSymbols(**input); 19437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pModule.getLibraryList().push_back(*input); 19537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (doContinue && m_ArchiveReader.isMyFormat(**input, doContinue)) { 19637b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*input)->setType(Input::Archive); 19737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_Config.options().isInExcludeLIBS(**input)) { 19837b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*input)->setNoExport(); 19937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 20037b74a387bb3993387029859c2d9d051c41c724eStephen Hines Archive archive(**input, m_Builder); 20137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ArchiveReader.readArchive(m_Config, archive); 20237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (archive.numOfObjectMember() > 0) { 20337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_InputTree.merge<InputTree::Inclusive>(input, archive.inputs()); 20437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 20537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 20637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_Config.options().warnMismatch()) 20737b74a387bb3993387029859c2d9d051c41c724eStephen Hines warning(diag::warn_unrecognized_input_file) 20837b74a387bb3993387029859c2d9d051c41c724eStephen Hines << (*input)->path() << m_Config.targets().triple().str(); 20937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 21037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 21137b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 21237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 21337b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 214