MemoryAreaFactory.cpp revision affc150dc44fab1911775a49636d0ce85333b634
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
15using namespace mcld;
16
17//===----------------------------------------------------------------------===//
18// MemoryAreaFactory
19MemoryAreaFactory::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
27MemoryAreaFactory::~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
40MemoryArea*
41MemoryAreaFactory::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
63MemoryArea*
64MemoryAreaFactory::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
87void 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
96MemoryArea*
97MemoryAreaFactory::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
105MemoryArea*
106MemoryAreaFactory::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