1 //===- MCLDFile.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 // MCLDFile represents a file, the content of the file is stored in LDContext.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef MCLD_LD_FILE_H
15 #define MCLD_LD_FILE_H
16 #ifdef ENABLE_UNITTEST
17 #include <gtest.h>
18 #endif
19
20 #include "mcld/ADT/Uncopyable.h"
21 #include "mcld/LD/LDContext.h"
22 #include "mcld/Support/Path.h"
23 #include "mcld/Support/FileSystem.h"
24 #include "mcld/Support/GCFactory.h"
25 #include "mcld/Support/MemoryArea.h"
26 #include <llvm/ADT/StringRef.h>
27 #include <string>
28 #include <sys/stat.h>
29
30
31 namespace mcld
32 {
33 class MemoryArea;
34
35 /** \class MCLDFile
36 * \brief MCLDFile represents the file being linked or produced.
37 *
38 * MCLDFile is the storage of name, path and type
39 * A MCLDFile just refers to LDContext, not owns it.
40 *
41 * @see mcld::sys::fs::Path LDContext
42 */
43 class MCLDFile : private Uncopyable
44 {
45 public:
46 enum Type {
47 Unknown,
48 Object,
49 Exec,
50 DynObj,
51 CoreFile,
52 Script,
53 Archive,
54 External
55 };
56
57 public:
58 MCLDFile();
59 MCLDFile(llvm::StringRef pName);
60 MCLDFile(llvm::StringRef pName,
61 const sys::fs::Path& pPath,
62 unsigned int pType = Unknown);
63
64 virtual ~MCLDFile();
65
66 // ----- modifiers ----- //
setType(unsigned int pType)67 void setType(unsigned int pType)
68 { m_Type = pType; }
69
setContext(LDContext * pContext)70 void setContext(LDContext* pContext)
71 { m_pContext = pContext; }
72
setPath(const sys::fs::Path & pPath)73 void setPath(const sys::fs::Path& pPath)
74 { m_Path = pPath; }
75
setMemArea(MemoryArea * pMemArea)76 void setMemArea(MemoryArea* pMemArea)
77 {
78 m_pMemArea = pMemArea;
79 }
80
81 /// setSOName - set the name of the shared object.
82 /// In ELF, this will be written in DT_SONAME
83 void setSOName(const std::string& pName);
84
85 // ----- observers ----- //
type()86 unsigned int type() const
87 { return m_Type; }
88
name()89 const std::string& name() const
90 { return m_Name; }
91
path()92 const sys::fs::Path& path() const
93 { return m_Path; }
94
hasContext()95 bool hasContext() const
96 { return (0 != m_pContext); }
97
context()98 LDContext* context()
99 { return m_pContext; }
100
context()101 const LDContext* context() const
102 { return m_pContext; }
103
hasMemArea()104 bool hasMemArea() const
105 { return (0 != m_pMemArea); }
106
memArea()107 MemoryArea* memArea()
108 { return m_pMemArea; }
109
memArea()110 const MemoryArea* memArea() const
111 { return m_pMemArea; }
112
113 protected:
114 unsigned int m_Type;
115 LDContext *m_pContext;
116 sys::fs::Path m_Path;
117 std::string m_Name;
118 MemoryArea* m_pMemArea;
119 };
120
121 /** \class MCLDFileFactory
122 * \brief MCLDFileFactory controls the production and destruction of
123 * MCLDFiles.
124 *
125 * All MCLDFiles created by MCLDFileFactory are guaranteed to be destructed
126 * while MCLDFileFactory is destructed.
127 *
128 * MCLDFileFactory also provides the MCLCContextFactory to MCLDFile.
129 * MCLDFile is responsed for the life of LDContext, therefore, the best
130 * idea is let MCLDFile control the life of LDContext. Since SectLinker
131 * has the need to count the number of LDContext, we give a central factory
132 * for LDContext.
133 *
134 * \see llvm::sys::Path
135 */
136 template<size_t NUM>
137 class MCLDFileFactory : public GCFactory<MCLDFile, NUM>
138 {
139 public:
140 typedef GCFactory<MCLDFile, NUM> Alloc;
141
142 public:
143 // ----- production ----- //
144 MCLDFile* produce(llvm::StringRef pName,
145 const sys::fs::Path& pPath,
146 unsigned int pType = MCLDFile::Unknown);
147
148 MCLDFile* produce();
149 };
150
151 } // namespace of mcld
152
153 //===----------------------------------------------------------------------===//
154 // MCLDFileFactory
155 template<size_t NUM>
produce(llvm::StringRef pName,const mcld::sys::fs::Path & pPath,unsigned int pType)156 mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce(llvm::StringRef pName,
157 const mcld::sys::fs::Path& pPath,
158 unsigned int pType)
159 {
160 mcld::MCLDFile* result = Alloc::allocate();
161 new (result) mcld::MCLDFile(pName, pPath, pType);
162 return result;
163 }
164
165 template<size_t NUM>
produce()166 mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce()
167 {
168 mcld::MCLDFile* result = Alloc::allocate();
169 new (result) mcld::MCLDFile();
170 return result;
171 }
172
173 #endif
174
175