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#ifndef MCLD_OBJECT_OBJECTLINKER_H_
10#define MCLD_OBJECT_OBJECTLINKER_H_
11#include <llvm/Support/DataTypes.h>
12
13namespace mcld {
14
15class ArchiveReader;
16class BinaryReader;
17class BinaryWriter;
18class DynObjReader;
19class DynObjWriter;
20class ExecWriter;
21class FileOutputBuffer;
22class GroupReader;
23class IRBuilder;
24class LinkerConfig;
25class Module;
26class ObjectReader;
27class ObjectWriter;
28class Relocation;
29class ResolveInfo;
30class ScriptReader;
31class TargetLDBackend;
32
33/** \class ObjectLinker
34 */
35class ObjectLinker {
36 public:
37  ObjectLinker(const LinkerConfig& pConfig, TargetLDBackend& pLDBackend);
38
39  ~ObjectLinker();
40
41  bool initialize(Module& pModule, IRBuilder& pBuilder);
42
43  /// initStdSections - initialize standard sections of the output file.
44  bool initStdSections();
45
46  /// addUndefinedSymbols - add symbols set by -u
47  void addUndefinedSymbols();
48
49  /// normalize - normalize the input files
50  void normalize();
51
52  /// linkable - check the linkability of current LinkerConfig
53  ///  Check list:
54  ///  - check the Attributes are not violate the constaint
55  ///  - check every Input has a correct Attribute
56  bool linkable() const;
57
58  /// readRelocations - read all relocation entries
59  bool readRelocations();
60
61  /// dataStrippingOpt - optimizations for reducing code size
62  void dataStrippingOpt();
63
64  /// mergeSections - put allinput sections into output sections
65  bool mergeSections();
66
67  /// addSymbolsToOutput - after all symbols has been resolved, add the symbol
68  /// to output
69  void addSymbolsToOutput(Module& pModule);
70
71  /// allocateCommonSymobols - allocate fragments for common symbols to the
72  /// corresponding sections
73  bool allocateCommonSymbols();
74
75  /// addStandardSymbols - shared object and executable files need some
76  /// standard symbols
77  ///   @return if there are some input symbols with the same name to the
78  ///   standard symbols, return false
79  bool addStandardSymbols();
80
81  /// addTargetSymbols - some targets, such as MIPS and ARM, need some
82  /// target-dependent symbols
83  ///   @return if there are some input symbols with the same name to the
84  ///   target symbols, return false
85  bool addTargetSymbols();
86
87  /// addScriptSymbols - define symbols from the command line option or linker
88  /// scripts.
89  bool addScriptSymbols();
90
91  /// scanRelocations - scan all relocation entries by output symbols.
92  bool scanRelocations();
93
94  /// initStubs - initialize stub-related stuff.
95  bool initStubs();
96
97  /// prelayout - help backend to do some modification before layout
98  bool prelayout();
99
100  /// layout - linearly layout all output sections and reserve some space
101  /// for GOT/PLT
102  ///   Because we do not support instruction relaxing in this early version,
103  ///   if there is a branch can not jump to its target, we return false
104  ///   directly
105  bool layout();
106
107  /// postlayout - help backend to do some modification after layout
108  bool postlayout();
109
110  /// relocate - applying relocation entries and create relocation
111  /// section in the output files
112  /// Create relocation section, asking TargetLDBackend to
113  /// read the relocation information into RelocationEntry
114  /// and push_back into the relocation section
115  bool relocation();
116
117  /// finalizeSymbolValue - finalize the symbol value
118  bool finalizeSymbolValue();
119
120  /// emitOutput - emit the output file.
121  bool emitOutput(FileOutputBuffer& pOutput);
122
123  /// postProcessing - do modificatiion after all processes
124  bool postProcessing(FileOutputBuffer& pOutput);
125
126  // -----  readers and writers  ----- //
127  const ObjectReader* getObjectReader() const { return m_pObjectReader; }
128  ObjectReader* getObjectReader() { return m_pObjectReader; }
129
130  const DynObjReader* getDynObjReader() const { return m_pDynObjReader; }
131  DynObjReader* getDynObjReader() { return m_pDynObjReader; }
132
133  const ArchiveReader* getArchiveReader() const { return m_pArchiveReader; }
134  ArchiveReader* getArchiveReader() { return m_pArchiveReader; }
135
136  const GroupReader* getGroupReader() const { return m_pGroupReader; }
137  GroupReader* getGroupReader() { return m_pGroupReader; }
138
139  const BinaryReader* getBinaryReader() const { return m_pBinaryReader; }
140  BinaryReader* getBinaryReader() { return m_pBinaryReader; }
141
142  const ScriptReader* getScriptReader() const { return m_pScriptReader; }
143  ScriptReader* getScriptReader() { return m_pScriptReader; }
144
145  const ObjectWriter* getWriter() const { return m_pWriter; }
146  ObjectWriter* getWriter() { return m_pWriter; }
147
148 private:
149  /// normalSyncRelocationResult - sync relocation result when producing shared
150  /// objects or executables
151  void normalSyncRelocationResult(FileOutputBuffer& pOutput);
152
153  /// partialSyncRelocationResult - sync relocation result when doing partial
154  /// link
155  void partialSyncRelocationResult(FileOutputBuffer& pOutput);
156
157  /// writeRelocationResult - helper function of syncRelocationResult, write
158  /// relocation target data to output
159  void writeRelocationResult(Relocation& pReloc, uint8_t* pOutput);
160
161  /// addSymbolToOutput - add a symbol to output symbol table if it's not a
162  /// section symbol and not defined in the discarded section
163  void addSymbolToOutput(ResolveInfo& pInfo, Module& pModule);
164
165 private:
166  const LinkerConfig& m_Config;
167  Module* m_pModule;
168  IRBuilder* m_pBuilder;
169
170  TargetLDBackend& m_LDBackend;
171
172  // -----  readers and writers  ----- //
173  ObjectReader* m_pObjectReader;
174  DynObjReader* m_pDynObjReader;
175  ArchiveReader* m_pArchiveReader;
176  GroupReader* m_pGroupReader;
177  BinaryReader* m_pBinaryReader;
178  ScriptReader* m_pScriptReader;
179  ObjectWriter* m_pWriter;
180};
181
182}  // namespace mcld
183
184#endif  // MCLD_OBJECT_OBJECTLINKER_H_
185