• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- MemoryAreaFactory.cpp ----------------------------------------------===//
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 #include <mcld/Support/MemoryAreaFactory.h>
10 #include <mcld/Support/MsgHandling.h>
11 #include <mcld/Support/RegionFactory.h>
12 #include <mcld/Support/SystemUtils.h>
13 #include <mcld/Support/Space.h>
14 
15 using namespace mcld;
16 
17 //===----------------------------------------------------------------------===//
18 // MemoryAreaFactory
MemoryAreaFactory(size_t pNum)19 MemoryAreaFactory::MemoryAreaFactory(size_t pNum)
20   : GCFactory<MemoryArea, 0>(pNum) {
21   // For each loaded file, MCLinker must load ELF header, section header,
22   // symbol table, and string table. So, we set the size of chunk quadruple
23   // larger than the number of input files.
24   m_pRegionFactory = new RegionFactory(pNum*4);
25 }
26 
~MemoryAreaFactory()27 MemoryAreaFactory::~MemoryAreaFactory()
28 {
29   HandleToArea::iterator rec, rEnd = m_HandleToArea.end();
30   for (rec = m_HandleToArea.begin(); rec != rEnd; ++rec) {
31     if (rec->handle->isOpened()) {
32       rec->handle->close();
33     }
34     delete rec->handle;
35   }
36 
37   delete m_pRegionFactory;
38 }
39 
40 MemoryArea*
produce(const sys::fs::Path & pPath,FileHandle::OpenMode pMode)41 MemoryAreaFactory::produce(const sys::fs::Path& pPath,
42                            FileHandle::OpenMode pMode)
43 {
44   HandleToArea::Result map_result = m_HandleToArea.findFirst(pPath);
45   if (NULL == map_result.area) {
46     // can not found
47     FileHandle* handler = new FileHandle();
48     if (!handler->open(pPath, pMode)) {
49       error(diag::err_cannot_open_file) << pPath
50                                         << sys::strerror(handler->error());
51     }
52 
53     MemoryArea* result = allocate();
54     new (result) MemoryArea(*m_pRegionFactory, *handler);
55 
56     m_HandleToArea.push_back(handler, result);
57     return result;
58   }
59 
60   return map_result.area;
61 }
62 
63 MemoryArea*
produce(const sys::fs::Path & pPath,FileHandle::OpenMode pMode,FileHandle::Permission pPerm)64 MemoryAreaFactory::produce(const sys::fs::Path& pPath,
65                            FileHandle::OpenMode pMode,
66                            FileHandle::Permission pPerm)
67 {
68   HandleToArea::Result map_result = m_HandleToArea.findFirst(pPath);
69   if (NULL == map_result.area) {
70     // can not found
71     FileHandle* handler = new FileHandle();
72     if (!handler->open(pPath, pMode, pPerm)) {
73       error(diag::err_cannot_open_file) << pPath
74                                         << sys::strerror(handler->error());
75     }
76 
77     MemoryArea* result = allocate();
78     new (result) MemoryArea(*m_pRegionFactory, *handler);
79 
80     m_HandleToArea.push_back(handler, result);
81     return result;
82   }
83 
84   return map_result.area;
85 }
86 
destruct(MemoryArea * pArea)87 void MemoryAreaFactory::destruct(MemoryArea* pArea)
88 {
89   m_HandleToArea.erase(pArea);
90   pArea->clear();
91   pArea->handler()->close();
92   destroy(pArea);
93   deallocate(pArea);
94 }
95 
96 MemoryArea*
create(void * pMemBuffer,size_t pSize)97 MemoryAreaFactory::create(void* pMemBuffer, size_t pSize)
98 {
99   Space* space = new Space(Space::EXTERNAL, pMemBuffer, pSize);
100   MemoryArea* result = allocate();
101   new (result) MemoryArea(*m_pRegionFactory, *space);
102   return result;
103 }
104 
105 MemoryArea*
create(int pFD,FileHandle::OpenMode pMode)106 MemoryAreaFactory::create(int pFD, FileHandle::OpenMode pMode)
107 {
108   FileHandle* handler = new FileHandle();
109   handler->delegate(pFD, pMode);
110 
111   MemoryArea* result = allocate();
112   new (result) MemoryArea(*m_pRegionFactory, *handler);
113 
114   return result;
115 }
116 
117