15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MemoryAreaFactory.cpp ----------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
9affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryAreaFactory.h>
10affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
11affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/RegionFactory.h>
12affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/SystemUtils.h>
13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/Space.h>
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// MemoryAreaFactory
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMemoryAreaFactory::MemoryAreaFactory(size_t pNum)
20affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  : GCFactory<MemoryArea, 0>(pNum) {
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // For each loaded file, MCLinker must load ELF header, section header,
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // symbol table, and string table. So, we set the size of chunk quadruple
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // larger than the number of input files.
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pRegionFactory = new RegionFactory(pNum*4);
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMemoryAreaFactory::~MemoryAreaFactory()
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  HandleToArea::iterator rec, rEnd = m_HandleToArea.end();
30affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (rec = m_HandleToArea.begin(); rec != rEnd; ++rec) {
31affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (rec->handle->isOpened()) {
32affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      rec->handle->close();
33affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
34affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    delete rec->handle;
35affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  delete m_pRegionFactory;
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
40affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryArea*
41affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryAreaFactory::produce(const sys::fs::Path& pPath,
42affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           FileHandle::OpenMode pMode)
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
44affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  HandleToArea::Result map_result = m_HandleToArea.findFirst(pPath);
45affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == map_result.area) {
46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // can not found
47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    FileHandle* handler = new FileHandle();
48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!handler->open(pPath, pMode)) {
49affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      error(diag::err_cannot_open_file) << pPath
50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        << sys::strerror(handler->error());
51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    MemoryArea* result = allocate();
54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    new (result) MemoryArea(*m_pRegionFactory, *handler);
55affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
56affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_HandleToArea.push_back(handler, result);
57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return result;
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
60affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return map_result.area;
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
63affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryArea*
64affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryAreaFactory::produce(const sys::fs::Path& pPath,
65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           FileHandle::OpenMode pMode,
66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           FileHandle::Permission pPerm)
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  HandleToArea::Result map_result = m_HandleToArea.findFirst(pPath);
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == map_result.area) {
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // can not found
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    FileHandle* handler = new FileHandle();
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (!handler->open(pPath, pMode, pPerm)) {
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      error(diag::err_cannot_open_file) << pPath
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        << sys::strerror(handler->error());
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    MemoryArea* result = allocate();
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    new (result) MemoryArea(*m_pRegionFactory, *handler);
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_HandleToArea.push_back(handler, result);
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return result;
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return map_result.area;
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
87affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid MemoryAreaFactory::destruct(MemoryArea* pArea)
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_HandleToArea.erase(pArea);
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  pArea->clear();
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  pArea->handler()->close();
92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  destroy(pArea);
93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  deallocate(pArea);
94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
96affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryArea*
97affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryAreaFactory::create(void* pMemBuffer, size_t pSize)
98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  Space* space = new Space(Space::EXTERNAL, pMemBuffer, pSize);
100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  MemoryArea* result = allocate();
101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  new (result) MemoryArea(*m_pRegionFactory, *space);
102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return result;
103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
105affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryArea*
106affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryAreaFactory::create(int pFD, FileHandle::OpenMode pMode)
107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  FileHandle* handler = new FileHandle();
109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  handler->delegate(pFD, pMode);
110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  MemoryArea* result = allocate();
112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  new (result) MemoryArea(*m_pRegionFactory, *handler);
113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
117