ObjectLinker.h revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
1//===- ObjectLinker.h -----------------------------------------------------===//
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//
10// ObjectLinker plays the same role as GNU collect2 to prepare all implicit
11// parameters for FragmentLinker.
12//
13//===----------------------------------------------------------------------===//
14#ifndef MCLD_OBJECT_OBJECT_LINKER_H
15#define MCLD_OBJECT_OBJECT_LINKER_H
16#ifdef ENABLE_UNITTEST
17#include <gtest.h>
18#endif
19#include <stddef.h>
20
21namespace mcld {
22
23class Module;
24class LinkerConfig;
25class InputBuilder;
26class FragmentLinker;
27class TargetLDBackend;
28class MemoryArea;
29class MemoryAreaFactory;
30class ObjectReader;
31class DynObjReader;
32class ArchiveReader;
33class GroupReader;
34class ObjectWriter;
35class DynObjWriter;
36class ExecWriter;
37
38/** \class ObjectLinker
39 *  \brief ObjectLinker prepares parameters for FragmentLinker.
40 */
41class ObjectLinker
42{
43public:
44  ObjectLinker(const LinkerConfig& pConfig,
45               Module& pModule,
46               InputBuilder& pInputBuilder,
47               TargetLDBackend& pLDBackend);
48
49  ~ObjectLinker();
50
51  /// initFragmentLinker - initialize FragmentLinker
52  ///  Connect all components in FragmentLinker
53  bool initFragmentLinker();
54
55  /// initStdSections - initialize standard sections of the output file.
56  bool initStdSections();
57
58  /// normalize - normalize the input files
59  void normalize();
60
61  /// linkable - check the linkability of current LinkerConfig
62  ///  Check list:
63  ///  - check the Attributes are not violate the constaint
64  ///  - check every Input has a correct Attribute
65  bool linkable() const;
66
67  /// readRelocations - read all relocation entries
68  bool readRelocations();
69
70  /// mergeSections - put allinput sections into output sections
71  bool mergeSections();
72
73  /// addStandardSymbols - shared object and executable files need some
74  /// standard symbols
75  ///   @return if there are some input symbols with the same name to the
76  ///   standard symbols, return false
77  bool addStandardSymbols();
78
79  /// addTargetSymbols - some targets, such as MIPS and ARM, need some
80  /// target-dependent symbols
81  ///   @return if there are some input symbols with the same name to the
82  ///   target symbols, return false
83  bool addTargetSymbols();
84
85  /// scanRelocations - scan all relocation entries by output symbols.
86  bool scanRelocations();
87
88  /// prelayout - help backend to do some modification before layout
89  bool prelayout();
90
91  /// layout - linearly layout all output sections and reserve some space
92  /// for GOT/PLT
93  ///   Because we do not support instruction relaxing in this early version,
94  ///   if there is a branch can not jump to its target, we return false
95  ///   directly
96  bool layout();
97
98  /// postlayout - help backend to do some modification after layout
99  bool postlayout();
100
101  /// relocate - applying relocation entries and create relocation
102  /// section in the output files
103  /// Create relocation section, asking TargetLDBackend to
104  /// read the relocation information into RelocationEntry
105  /// and push_back into the relocation section
106  bool relocation();
107
108  /// finalizeSymbolValue - finalize the symbol value
109  bool finalizeSymbolValue();
110
111  /// emitOutput - emit the output file.
112  bool emitOutput(MemoryArea& pOutput);
113
114  /// postProcessing - do modificatiion after all processes
115  bool postProcessing(MemoryArea& pOutput);
116
117  /// getLinker - get internal FragmentLinker object
118  const FragmentLinker* getLinker() const { return m_pLinker; }
119  FragmentLinker*       getLinker()       { return m_pLinker; }
120
121  /// hasInitLinker - has Linker been initialized?
122  bool hasInitLinker() const
123  { return (NULL != m_pLinker); }
124
125  // -----  readers and writers  ----- //
126  const ObjectReader*  getObjectReader () const { return m_pObjectReader;  }
127  ObjectReader*        getObjectReader ()       { return m_pObjectReader;  }
128
129  const DynObjReader*  getDynObjReader () const { return m_pDynObjReader;  }
130  DynObjReader*        getDynObjReader ()       { return m_pDynObjReader;  }
131
132  const ArchiveReader* getArchiveReader() const { return m_pArchiveReader; }
133  ArchiveReader*       getArchiveReader()       { return m_pArchiveReader; }
134
135  const GroupReader* getGroupReader() const { return m_pGroupReader; }
136  GroupReader*       getGroupReader()       { return m_pGroupReader; }
137
138  const ObjectWriter*  getObjectWriter () const { return m_pObjectWriter;  }
139  ObjectWriter*        getObjectWriter ()       { return m_pObjectWriter;  }
140
141  const DynObjWriter*  getDynObjWriter () const { return m_pDynObjWriter;  }
142  DynObjWriter*        getDynObjWriter ()       { return m_pDynObjWriter;  }
143
144  const ExecWriter*    getExecWriter   () const { return m_pExecWriter;    }
145  ExecWriter*          getExecWriter   ()       { return m_pExecWriter;    }
146
147private:
148  const LinkerConfig& m_Config;
149  Module& m_Module;
150
151  // we pass in InputBuilder for Archive and GroupReader.
152  InputBuilder& m_InputBuilder;
153
154  FragmentLinker* m_pLinker;
155  TargetLDBackend &m_LDBackend;
156
157  // -----  readers and writers  ----- //
158  ObjectReader* m_pObjectReader;
159  DynObjReader* m_pDynObjReader;
160  ArchiveReader* m_pArchiveReader;
161  ObjectWriter* m_pObjectWriter;
162  DynObjWriter* m_pDynObjWriter;
163  ExecWriter* m_pExecWriter;
164  GroupReader* m_pGroupReader;
165};
166
167} // end namespace mcld
168#endif
169