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