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
GroupReader(Module & pModule,ObjectReader & pObjectReader,DynObjReader & pDynObjReader,ArchiveReader & pArchiveReader,BinaryReader & pBinaryReader)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
~GroupReader()34 GroupReader::~GroupReader()
35 {
36 }
37
readGroup(Module::input_iterator pRoot,Module::input_iterator pEnd,InputBuilder & pBuilder,const LinkerConfig & pConfig)38 bool 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