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_LDFILE_H 15 #define MCLD_LDFILE_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 }; 55 56 public: 57 MCLDFile(); 58 MCLDFile(llvm::StringRef pName); 59 MCLDFile(llvm::StringRef pName, 60 const sys::fs::Path& pPath, 61 unsigned int pType = Unknown); 62 63 virtual ~MCLDFile(); 64 65 // ----- modifiers ----- // 66 void setType(unsigned int pType) 67 { m_Type = pType; } 68 69 void setContext(LDContext* pContext) 70 { m_pContext = pContext; } 71 72 void setPath(const sys::fs::Path& pPath) 73 { m_Path = pPath; } 74 75 void setMemArea(MemoryArea* pMemArea) 76 { 77 m_pMemArea = pMemArea; 78 } 79 80 /// setSOName - set the name of the shared object. 81 /// In ELF, this will be written in DT_SONAME 82 void setSOName(const std::string& pName); 83 84 // ----- observers ----- // 85 unsigned int type() const 86 { return m_Type; } 87 88 const std::string& name() const 89 { return m_Name; } 90 91 const sys::fs::Path& path() const 92 { return m_Path; } 93 94 bool hasContext() const 95 { return (0 != m_pContext); } 96 97 LDContext* context() 98 { return m_pContext; } 99 100 const LDContext* context() const 101 { return m_pContext; } 102 103 bool hasMemArea() const 104 { return (0 != m_pMemArea); } 105 106 MemoryArea* memArea() 107 { return m_pMemArea; } 108 109 const MemoryArea* memArea() const 110 { return m_pMemArea; } 111 112 protected: 113 unsigned int m_Type; 114 LDContext *m_pContext; 115 sys::fs::Path m_Path; 116 std::string m_Name; 117 MemoryArea* m_pMemArea; 118 }; 119 120 /** \class MCLDFileFactory 121 * \brief MCLDFileFactory controls the production and destruction of 122 * MCLDFiles. 123 * 124 * All MCLDFiles created by MCLDFileFactory are guaranteed to be destructed 125 * while MCLDFileFactory is destructed. 126 * 127 * MCLDFileFactory also provides the MCLCContextFactory to MCLDFile. 128 * MCLDFile is responsed for the life of LDContext, therefore, the best 129 * idea is let MCLDFile control the life of LDContext. Since SectLinker 130 * has the need to count the number of LDContext, we give a central factory 131 * for LDContext. 132 * 133 * \see llvm::sys::Path 134 */ 135 template<size_t NUM> 136 class MCLDFileFactory : public GCFactory<MCLDFile, NUM> 137 { 138 public: 139 typedef GCFactory<MCLDFile, NUM> Alloc; 140 141 public: 142 // ----- production ----- // 143 MCLDFile* produce(llvm::StringRef pName, 144 const sys::fs::Path& pPath, 145 unsigned int pType = MCLDFile::Unknown); 146 147 MCLDFile* produce(); 148 }; 149 150 } // namespace of mcld 151 152 //===----------------------------------------------------------------------===// 153 // MCLDFileFactory 154 template<size_t NUM> 155 mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce(llvm::StringRef pName, 156 const mcld::sys::fs::Path& pPath, 157 unsigned int pType) 158 { 159 mcld::MCLDFile* result = Alloc::allocate(); 160 new (result) mcld::MCLDFile(pName, pPath, pType); 161 return result; 162 } 163 164 template<size_t NUM> 165 mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce() 166 { 167 mcld::MCLDFile* result = Alloc::allocate(); 168 new (result) mcld::MCLDFile(); 169 return result; 170 } 171 172 #endif 173 174