GroupReader.cpp revision f33f6de54db174aa679a4b6d1e040d37e95541c0
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 19using namespace mcld; 20 21GroupReader::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 34GroupReader::~GroupReader() 35{ 36} 37 38bool GroupReader::readGroup(Module::input_iterator pRoot, 39 Module::input_iterator pEnd, 40 InputBuilder& pBuilder, 41 const LinkerConfig& pConfig) 42{ 43 // record the number of total objects included in this sub-tree 44 size_t cur_obj_cnt = 0; 45 size_t last_obj_cnt = 0; 46 size_t non_ar_obj_cnt = 0; 47 48 // record the archive files in this sub-tree 49 typedef std::vector<ArchiveListEntry*> ArchiveListType; 50 ArchiveListType ar_list; 51 52 Module::input_iterator input = --pRoot; 53 54 // first time read the sub-tree 55 while (input != pEnd) { 56 // already got type - for example, bitcode or external OIR (object 57 // intermediate representation) 58 if ((*input)->type() == Input::Script || 59 (*input)->type() == Input::Archive || 60 (*input)->type() == Input::External) { 61 ++input; 62 continue; 63 } 64 65 if (Input::Object == (*input)->type()) { 66 m_Module.getObjectList().push_back(*input); 67 continue; 68 } 69 70 if (Input::DynObj == (*input)->type()) { 71 m_Module.getLibraryList().push_back(*input); 72 continue; 73 } 74 75 bool doContinue = false; 76 // is an archive 77 if (m_ArchiveReader.isMyFormat(**input, doContinue)) { 78 (*input)->setType(Input::Archive); 79 // record the Archive used by each archive node 80 Archive* ar = new Archive(**input, pBuilder); 81 ArchiveListEntry* entry = new ArchiveListEntry(*ar, input); 82 ar_list.push_back(entry); 83 // read archive 84 m_ArchiveReader.readArchive(pConfig, *ar); 85 cur_obj_cnt += ar->numOfObjectMember(); 86 } 87 // read input as a binary file 88 else if (doContinue && m_BinaryReader.isMyFormat(**input, doContinue)) { 89 (*input)->setType(Input::Object); 90 m_BinaryReader.readBinary(**input); 91 m_Module.getObjectList().push_back(*input); 92 } 93 // is a relocatable object file 94 else if (doContinue && m_ObjectReader.isMyFormat(**input, doContinue)) { 95 (*input)->setType(Input::Object); 96 m_ObjectReader.readHeader(**input); 97 m_ObjectReader.readSections(**input); 98 m_ObjectReader.readSymbols(**input); 99 m_Module.getObjectList().push_back(*input); 100 ++cur_obj_cnt; 101 ++non_ar_obj_cnt; 102 } 103 // is a shared object file 104 else if (doContinue && m_DynObjReader.isMyFormat(**input, doContinue)) { 105 (*input)->setType(Input::DynObj); 106 m_DynObjReader.readHeader(**input); 107 m_DynObjReader.readSymbols(**input); 108 m_Module.getLibraryList().push_back(*input); 109 } 110 else { 111 warning(diag::warn_unrecognized_input_file) << (*input)->path() 112 << pConfig.targets().triple().str(); 113 } 114 ++input; 115 } 116 117 // after read in all the archives, traverse the archive list in a loop until 118 // there is no unresolved symbols added 119 ArchiveListType::iterator it = ar_list.begin(); 120 ArchiveListType::iterator end = ar_list.end(); 121 while (cur_obj_cnt != last_obj_cnt) { 122 last_obj_cnt = cur_obj_cnt; 123 cur_obj_cnt = non_ar_obj_cnt; 124 for (it = ar_list.begin(); it != end; ++it) { 125 Archive& ar = (*it)->archive; 126 // if --whole-archive is given to this archive, no need to read it again 127 if ( ar.getARFile().attribute()->isWholeArchive()) 128 continue; 129 m_ArchiveReader.readArchive(pConfig, ar); 130 cur_obj_cnt += ar.numOfObjectMember(); 131 } 132 } 133 134 // after all needed member included, merge the archive sub-tree to main 135 // InputTree 136 for (it = ar_list.begin(); it != end; ++it) { 137 Archive& ar = (*it)->archive; 138 if (ar.numOfObjectMember() > 0) { 139 m_Module.getInputTree().merge<InputTree::Inclusive>((*it)->input, 140 ar.inputs()); 141 } 142 } 143 144 // cleanup ar_list 145 for (it = ar_list.begin(); it != end; ++it) { 146 delete &((*it)->archive); 147 delete (*it); 148 } 149 ar_list.clear(); 150 151 return true; 152} 153 154