1 //===- GroupReader.cpp ----------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #include <mcld/LD/Archive.h> 10 #include <mcld/LD/ArchiveReader.h> 11 #include <mcld/LD/DynObjReader.h> 12 #include <mcld/LD/GroupReader.h> 13 #include <mcld/LD/ObjectReader.h> 14 #include <mcld/LD/BinaryReader.h> 15 #include <mcld/LinkerConfig.h> 16 #include <mcld/MC/Attribute.h> 17 #include <mcld/Support/MsgHandling.h> 18 19 using namespace mcld; 20 21 GroupReader::GroupReader(Module& pModule, 22 ObjectReader& pObjectReader, 23 DynObjReader& pDynObjReader, 24 ArchiveReader& pArchiveReader, 25 BinaryReader& pBinaryReader) 26 : m_Module(pModule), 27 m_ObjectReader(pObjectReader), 28 m_DynObjReader(pDynObjReader), 29 m_ArchiveReader(pArchiveReader), 30 m_BinaryReader(pBinaryReader) 31 { 32 } 33 34 GroupReader::~GroupReader() 35 { 36 } 37 38 bool GroupReader::readGroup(Module::input_iterator pRoot, 39 InputBuilder& pBuilder, 40 const LinkerConfig& pConfig) 41 { 42 // record the number of total objects included in this sub-tree 43 size_t cur_obj_cnt = 0; 44 size_t last_obj_cnt = 0; 45 size_t non_ar_obj_cnt = 0; 46 47 // record the archive files in this sub-tree 48 typedef std::vector<ArchiveListEntry*> ArchiveListType; 49 ArchiveListType ar_list; 50 51 Module::input_iterator input = --pRoot; 52 53 // Since the end of a sub-tree is the same node to the end of whole tree, we 54 // take the end of the whole input tree for conventience. 55 Module::input_iterator input_end = m_Module.input_end(); 56 57 // first time read the sub-tree 58 while (input != input_end) { 59 // already got type - for example, bitcode or external OIR (object 60 // intermediate representation) 61 if ((*input)->type() == Input::Script || 62 (*input)->type() == Input::Archive || 63 (*input)->type() == Input::External) { 64 ++input; 65 continue; 66 } 67 68 if (Input::Object == (*input)->type()) { 69 m_Module.getObjectList().push_back(*input); 70 continue; 71 } 72 73 if (Input::DynObj == (*input)->type()) { 74 m_Module.getLibraryList().push_back(*input); 75 continue; 76 } 77 78 // is an archive 79 if (m_ArchiveReader.isMyFormat(**input)) { 80 (*input)->setType(Input::Archive); 81 // record the Archive used by each archive node 82 Archive* ar = new Archive(**input, pBuilder); 83 ArchiveListEntry* entry = new ArchiveListEntry(*ar, input); 84 ar_list.push_back(entry); 85 // read archive 86 m_ArchiveReader.readArchive(*ar); 87 cur_obj_cnt += ar->numOfObjectMember(); 88 } 89 // read input as a binary file 90 else if (pConfig.options().isBinaryInput()) { 91 (*input)->setType(Input::Object); 92 m_BinaryReader.readBinary(**input); 93 m_Module.getObjectList().push_back(*input); 94 } 95 // is a relocatable object file 96 else if (m_ObjectReader.isMyFormat(**input)) { 97 (*input)->setType(Input::Object); 98 m_ObjectReader.readHeader(**input); 99 m_ObjectReader.readSections(**input); 100 m_ObjectReader.readSymbols(**input); 101 m_Module.getObjectList().push_back(*input); 102 ++cur_obj_cnt; 103 ++non_ar_obj_cnt; 104 } 105 // is a shared object file 106 else if (m_DynObjReader.isMyFormat(**input)) { 107 (*input)->setType(Input::DynObj); 108 m_DynObjReader.readHeader(**input); 109 m_DynObjReader.readSymbols(**input); 110 m_Module.getLibraryList().push_back(*input); 111 } 112 else { 113 fatal(diag::err_unrecognized_input_file) << (*input)->path() 114 << pConfig.targets().triple().str(); 115 } 116 ++input; 117 } 118 119 // after read in all the archives, traverse the archive list in a loop until 120 // there is no unresolved symbols added 121 ArchiveListType::iterator it = ar_list.begin(); 122 ArchiveListType::iterator end = ar_list.end(); 123 while (cur_obj_cnt != last_obj_cnt) { 124 last_obj_cnt = cur_obj_cnt; 125 cur_obj_cnt = non_ar_obj_cnt; 126 for (it = ar_list.begin(); it != end; ++it) { 127 Archive& ar = (*it)->archive; 128 // if --whole-archive is given to this archive, no need to read it again 129 if ( ar.getARFile().attribute()->isWholeArchive()) 130 continue; 131 m_ArchiveReader.readArchive(ar); 132 cur_obj_cnt += ar.numOfObjectMember(); 133 } 134 } 135 136 // after all needed member included, merge the archive sub-tree to main 137 // InputTree 138 for (it = ar_list.begin(); it != end; ++it) { 139 Archive& ar = (*it)->archive; 140 if (ar.numOfObjectMember() > 0) { 141 m_Module.getInputTree().merge<InputTree::Inclusive>((*it)->input, 142 ar.inputs()); 143 } 144 } 145 146 // cleanup ar_list 147 for (it = ar_list.begin(); it != end; ++it) { 148 delete &((*it)->archive); 149 delete (*it); 150 } 151 ar_list.clear(); 152 153 return true; 154 } 155 156