19cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien//===- InputBuilder.cpp ---------------------------------------------------===// 29cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// 39cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// The MCLinker Project 49cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// 59cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// This file is distributed under the University of Illinois Open Source 69cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// License. See LICENSE.TXT for details. 79cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien// 89cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien//===----------------------------------------------------------------------===// 99cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#include "mcld/MC/InputBuilder.h" 109cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 119cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#include "mcld/LinkerConfig.h" 129cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#include "mcld/Config/Config.h" 139cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#include "mcld/MC/ContextFactory.h" 149cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#include "mcld/MC/InputFactory.h" 159cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#include "mcld/Support/MemoryAreaFactory.h" 169cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien#include "mcld/Support/Path.h" 179cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 189cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Leviennamespace mcld { 199cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 209cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph LevienInputBuilder::InputBuilder(const LinkerConfig& pConfig) 219cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien : m_Config(pConfig), 229cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pCurrentTree(NULL), 239cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pMove(NULL), 249cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_Root(), 259cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_bOwnFactory(true) { 269cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pInputFactory = new InputFactory(MCLD_NUM_OF_INPUTS, pConfig); 279cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pContextFactory = new ContextFactory(MCLD_NUM_OF_INPUTS); 289cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pMemFactory = new MemoryAreaFactory(MCLD_NUM_OF_INPUTS); 299cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 309cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 319cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph LevienInputBuilder::InputBuilder(const LinkerConfig& pConfig, 329cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien InputFactory& pInputFactory, 339cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien ContextFactory& pContextFactory, 349cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien MemoryAreaFactory& pMemoryFactory, 359cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien bool pDelegate) 369cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien : m_Config(pConfig), 379cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pInputFactory(&pInputFactory), 389cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pMemFactory(&pMemoryFactory), 399cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pContextFactory(&pContextFactory), 409cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pCurrentTree(NULL), 419cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pMove(NULL), 429cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_Root(), 439cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_bOwnFactory(pDelegate) { 449cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 459cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 469cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph LevienInputBuilder::~InputBuilder() { 479cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien if (m_bOwnFactory) { 489cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien delete m_pInputFactory; 499cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien delete m_pContextFactory; 509cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien delete m_pMemFactory; 519cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien } 529cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 539cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 549cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph LevienInput* InputBuilder::createInput(const std::string& pName, 559cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien const sys::fs::Path& pPath, 569cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien unsigned int pType, 579cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien off_t pFileOffset) { 589cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return m_pInputFactory->produce(pName, pPath, pType, pFileOffset); 599cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 609cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 619cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph LevienInputTree& InputBuilder::enterGroup() { 629cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien assert(m_pCurrentTree != NULL && m_pMove != NULL); 639cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 649cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pCurrentTree->enterGroup(m_Root, *m_pMove); 659cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pMove->move(m_Root); 669cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_ReturnStack.push(m_Root); 679cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pMove = &InputTree::Downward; 689cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 699cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return *m_pCurrentTree; 709cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 719cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 729cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph LevienInputTree& InputBuilder::exitGroup() { 739cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien assert(m_pCurrentTree != NULL && m_pMove != NULL); 749cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 759cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_Root = m_ReturnStack.top(); 769cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_ReturnStack.pop(); 779cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pMove = &InputTree::Afterward; 789cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 799cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return *m_pCurrentTree; 809cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 819cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 829cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienbool InputBuilder::isInGroup() const { 839cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return !m_ReturnStack.empty(); 849cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 859cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 869cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienconst InputTree& InputBuilder::getCurrentTree() const { 879cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien assert(m_pCurrentTree != NULL && m_pMove != NULL); 889cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return *m_pCurrentTree; 899cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 909cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 919cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph LevienInputTree& InputBuilder::getCurrentTree() { 929cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien assert(m_pCurrentTree != NULL && m_pMove != NULL); 939cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return *m_pCurrentTree; 949cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 959cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 969cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienvoid InputBuilder::setCurrentTree(InputTree& pInputTree) { 979cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pCurrentTree = &pInputTree; 989cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_Root = m_pCurrentTree->root(); 999cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien m_pMove = &InputTree::Downward; 1009cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 1019cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1029cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienbool InputBuilder::setContext(Input& pInput, bool pCheck) { 1039cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // The object files in an archive have common path. Every object files in an 1049cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // archive needs a individual context. We identify the object files in an 1059cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // archive by its file offset. Their file offsets are not zero. 1069cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien LDContext* context = NULL; 1079cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien if (pInput.fileOffset() != 0 || !pCheck) { 1089cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // pInput is an object in an archive file. Produce a new context in this 109329ae0639e332fa0ca85049f738776083b6dbafcBehdad Esfahbod // case. 110329ae0639e332fa0ca85049f738776083b6dbafcBehdad Esfahbod context = m_pContextFactory->produce(); 1119cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien } else { 1129cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // Using pInput.path() to avoid from creating context for identical file 1139cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien // twice. 1149cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien context = m_pContextFactory->produce(pInput.path()); 1159cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien } 1169cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1179cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien pInput.setContext(context); 1189cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return true; 1199cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 1209cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1219cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienbool InputBuilder::setMemory(Input& pInput, 1229cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien FileHandle::OpenMode pMode, 1239cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien FileHandle::Permission pPerm) { 1249cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien MemoryArea* memory = m_pMemFactory->produce(pInput.path(), pMode, pPerm); 1259cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien pInput.setMemArea(memory); 1269cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return true; 1279cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 1289cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1299cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienbool InputBuilder::setMemory(Input& pInput, void* pMemBuffer, size_t pSize) { 1309cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien MemoryArea* memory = m_pMemFactory->produce(pMemBuffer, pSize); 1319cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien pInput.setMemArea(memory); 1329cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return true; 1339cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 1349cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1359cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienconst AttrConstraint& InputBuilder::getConstraint() const { 1369cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return m_Config.attribute().constraint(); 1379cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 1389cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1399cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levienconst AttributeProxy& InputBuilder::getAttributes() const { 1409cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return m_pInputFactory->attr(); 1419cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 1429cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1439cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph LevienAttributeProxy& InputBuilder::getAttributes() { 1449cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien return m_pInputFactory->attr(); 1459cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} 1469cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien 1479cc9bbe1461f359f0b27c5e7645c17dda001ab1dRaph Levien} // namespace mcld 148