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