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 31namespace mcld 32{ 33class 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 */ 43class MCLDFile : private Uncopyable 44{ 45public: 46 enum Type { 47 Unknown, 48 Object, 49 Exec, 50 DynObj, 51 CoreFile, 52 Script, 53 Archive, 54 External 55 }; 56 57public: 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 113protected: 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 */ 136template<size_t NUM> 137class MCLDFileFactory : public GCFactory<MCLDFile, NUM> 138{ 139public: 140 typedef GCFactory<MCLDFile, NUM> Alloc; 141 142public: 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 155template<size_t NUM> 156mcld::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 165template<size_t NUM> 166mcld::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