122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- GroupReader.cpp ----------------------------------------------------===// 222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// 322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// The MCLinker Project 422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// 522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file is distributed under the University of Illinois Open Source 622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// License. See LICENSE.TXT for details. 722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// 822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/Archive.h> 1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ArchiveReader.h> 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/DynObjReader.h> 1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/GroupReader.h> 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ObjectReader.h> 14f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/BinaryReader.h> 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.h> 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MsgHandling.h> 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld; 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGroupReader::GroupReader(Module& pModule, 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ObjectReader& pObjectReader, 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao DynObjReader& pDynObjReader, 24f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ArchiveReader& pArchiveReader, 25f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines BinaryReader& pBinaryReader) 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : m_Module(pModule), 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ObjectReader(pObjectReader), 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_DynObjReader(pDynObjReader), 29f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_ArchiveReader(pArchiveReader), 30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_BinaryReader(pBinaryReader) 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGroupReader::~GroupReader() 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GroupReader::readGroup(Module::input_iterator pRoot, 39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Module::input_iterator pEnd, 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao InputBuilder& pBuilder, 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LinkerConfig& pConfig) 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // record the number of total objects included in this sub-tree 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t cur_obj_cnt = 0; 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t last_obj_cnt = 0; 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t non_ar_obj_cnt = 0; 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // record the archive files in this sub-tree 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao typedef std::vector<ArchiveListEntry*> ArchiveListType; 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ArchiveListType ar_list; 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::input_iterator input = --pRoot; 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // first time read the sub-tree 55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines while (input != pEnd) { 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // already got type - for example, bitcode or external OIR (object 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // intermediate representation) 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*input)->type() == Input::Script || 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->type() == Input::Archive || 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->type() == Input::External) { 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++input; 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 65f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (Input::Object == (*input)->type()) { 66f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_Module.getObjectList().push_back(*input); 67f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (Input::DynObj == (*input)->type()) { 71f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_Module.getLibraryList().push_back(*input); 72f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines bool doContinue = false; 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is an archive 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_ArchiveReader.isMyFormat(**input, doContinue)) { 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->setType(Input::Archive); 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // record the Archive used by each archive node 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Archive* ar = new Archive(**input, pBuilder); 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ArchiveListEntry* entry = new ArchiveListEntry(*ar, input); 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ar_list.push_back(entry); 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // read archive 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_ArchiveReader.readArchive(pConfig, *ar); 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_obj_cnt += ar->numOfObjectMember(); 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // read input as a binary file 88f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines else if (doContinue && m_BinaryReader.isMyFormat(**input, doContinue)) { 89f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*input)->setType(Input::Object); 90f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_BinaryReader.readBinary(**input); 91f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_Module.getObjectList().push_back(*input); 92f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is a relocatable object file 94f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines else if (doContinue && m_ObjectReader.isMyFormat(**input, doContinue)) { 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->setType(Input::Object); 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ObjectReader.readHeader(**input); 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ObjectReader.readSections(**input); 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ObjectReader.readSymbols(**input); 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Module.getObjectList().push_back(*input); 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++cur_obj_cnt; 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++non_ar_obj_cnt; 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is a shared object file 104f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines else if (doContinue && m_DynObjReader.isMyFormat(**input, doContinue)) { 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->setType(Input::DynObj); 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_DynObjReader.readHeader(**input); 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_DynObjReader.readSymbols(**input); 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Module.getLibraryList().push_back(*input); 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 111f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines warning(diag::warn_unrecognized_input_file) << (*input)->path() 112f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines << pConfig.targets().triple().str(); 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++input; 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // after read in all the archives, traverse the archive list in a loop until 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // there is no unresolved symbols added 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ArchiveListType::iterator it = ar_list.begin(); 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ArchiveListType::iterator end = ar_list.end(); 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao while (cur_obj_cnt != last_obj_cnt) { 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao last_obj_cnt = cur_obj_cnt; 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_obj_cnt = non_ar_obj_cnt; 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (it = ar_list.begin(); it != end; ++it) { 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Archive& ar = (*it)->archive; 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if --whole-archive is given to this archive, no need to read it again 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ( ar.getARFile().attribute()->isWholeArchive()) 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 129f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_ArchiveReader.readArchive(pConfig, ar); 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_obj_cnt += ar.numOfObjectMember(); 13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // after all needed member included, merge the archive sub-tree to main 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // InputTree 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (it = ar_list.begin(); it != end; ++it) { 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Archive& ar = (*it)->archive; 13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ar.numOfObjectMember() > 0) { 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Module.getInputTree().merge<InputTree::Inclusive>((*it)->input, 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ar.inputs()); 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // cleanup ar_list 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (it = ar_list.begin(); it != end; ++it) { 14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete &((*it)->archive); 14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete (*it); 14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ar_list.clear(); 15022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 154