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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/GroupReader.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/Archive.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ArchiveReader.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/BinaryReader.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/DynObjReader.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ObjectReader.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Attribute.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGroupReader::GroupReader(Module& pModule, 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ObjectReader& pObjectReader, 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao DynObjReader& pDynObjReader, 25f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ArchiveReader& pArchiveReader, 26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines BinaryReader& pBinaryReader) 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_Module(pModule), 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ObjectReader(pObjectReader), 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_DynObjReader(pDynObjReader), 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ArchiveReader(pArchiveReader), 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_BinaryReader(pBinaryReader) { 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3437b74a387bb3993387029859c2d9d051c41c724eStephen HinesGroupReader::~GroupReader() { 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GroupReader::readGroup(Module::input_iterator pRoot, 38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Module::input_iterator pEnd, 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao InputBuilder& pBuilder, 4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LinkerConfig& pConfig) { 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // record the number of total objects included in this sub-tree 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t cur_obj_cnt = 0; 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t last_obj_cnt = 0; 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t non_ar_obj_cnt = 0; 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // record the archive files in this sub-tree 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao typedef std::vector<ArchiveListEntry*> ArchiveListType; 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ArchiveListType ar_list; 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::input_iterator input = --pRoot; 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // first time read the sub-tree 53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines while (input != pEnd) { 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // already got type - for example, bitcode or external OIR (object 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // intermediate representation) 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*input)->type() == Input::Script || 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->type() == Input::Archive || 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->type() == Input::External) { 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++input; 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (Input::Object == (*input)->type()) { 64f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_Module.getObjectList().push_back(*input); 65f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 66f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 67f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (Input::DynObj == (*input)->type()) { 69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_Module.getLibraryList().push_back(*input); 70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 71f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 72f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines bool doContinue = false; 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // is an archive 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_ArchiveReader.isMyFormat(**input, doContinue)) { 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->setType(Input::Archive); 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // record the Archive used by each archive node 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Archive* ar = new Archive(**input, pBuilder); 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ArchiveListEntry* entry = new ArchiveListEntry(*ar, input); 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ar_list.push_back(entry); 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // read archive 82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_ArchiveReader.readArchive(pConfig, *ar); 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_obj_cnt += ar->numOfObjectMember(); 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (doContinue && m_BinaryReader.isMyFormat(**input, doContinue)) { 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines // read input as a binary file 86f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*input)->setType(Input::Object); 87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_BinaryReader.readBinary(**input); 88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_Module.getObjectList().push_back(*input); 8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (doContinue && m_ObjectReader.isMyFormat(**input, doContinue)) { 9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines // is a relocatable object file 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->setType(Input::Object); 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ObjectReader.readHeader(**input); 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ObjectReader.readSections(**input); 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ObjectReader.readSymbols(**input); 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Module.getObjectList().push_back(*input); 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++cur_obj_cnt; 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++non_ar_obj_cnt; 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (doContinue && m_DynObjReader.isMyFormat(**input, doContinue)) { 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines // is a shared object file 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (*input)->setType(Input::DynObj); 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_DynObjReader.readHeader(**input); 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_DynObjReader.readSymbols(**input); 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Module.getLibraryList().push_back(*input); 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines warning(diag::warn_unrecognized_input_file) 10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines << (*input)->path() << pConfig.targets().triple().str(); 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++input; 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // after read in all the archives, traverse the archive list in a loop until 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // there is no unresolved symbols added 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ArchiveListType::iterator it = ar_list.begin(); 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ArchiveListType::iterator end = ar_list.end(); 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao while (cur_obj_cnt != last_obj_cnt) { 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao last_obj_cnt = cur_obj_cnt; 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_obj_cnt = non_ar_obj_cnt; 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (it = ar_list.begin(); it != end; ++it) { 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Archive& ar = (*it)->archive; 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if --whole-archive is given to this archive, no need to read it again 12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (ar.getARFile().attribute()->isWholeArchive()) 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 123f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_ArchiveReader.readArchive(pConfig, ar); 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_obj_cnt += ar.numOfObjectMember(); 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // after all needed member included, merge the archive sub-tree to main 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // InputTree 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (it = ar_list.begin(); it != end; ++it) { 13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Archive& ar = (*it)->archive; 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ar.numOfObjectMember() > 0) { 13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Module.getInputTree().merge<InputTree::Inclusive>((*it)->input, 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ar.inputs()); 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // cleanup ar_list 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (it = ar_list.begin(); it != end; ++it) { 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete &((*it)->archive); 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao delete (*it); 14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ar_list.clear(); 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 14837b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 149