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