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 ----- // 67 void setType(unsigned int pType) 68 { m_Type = pType; } 69 70 void setContext(LDContext* pContext) 71 { m_pContext = pContext; } 72 73 void setPath(const sys::fs::Path& pPath) 74 { m_Path = pPath; } 75 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 ----- // 86 unsigned int type() const 87 { return m_Type; } 88 89 const std::string& name() const 90 { return m_Name; } 91 92 const sys::fs::Path& path() const 93 { return m_Path; } 94 95 bool hasContext() const 96 { return (0 != m_pContext); } 97 98 LDContext* context() 99 { return m_pContext; } 100 101 const LDContext* context() const 102 { return m_pContext; } 103 104 bool hasMemArea() const 105 { return (0 != m_pMemArea); } 106 107 MemoryArea* memArea() 108 { return m_pMemArea; } 109 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> 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> 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