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