15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MemoryArea.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//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryArea.h> 1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/Space.h> 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 12affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/FileHandle.h> 13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===// 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// MemoryArea 1967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//===--------------------------------------------------------------------===// 20affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// MemoryArea - special constructor 21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This constructor is used for *SPECIAL* situation. I'm sorry I can not 22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// reveal what is the special situation. 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMemoryArea::MemoryArea(Space& pUniverse) 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : m_pFileHandle(NULL) { 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_SpaceMap.insert(std::make_pair(Key(pUniverse.start(), pUniverse.size()), 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &pUniverse)); 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoMemoryArea::MemoryArea(FileHandle& pFileHandle) 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : m_pFileHandle(&pFileHandle) { 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 33affc150dc44fab1911775a49636d0ce85333b634Zonr ChangMemoryArea::~MemoryArea() 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The layout of MemorySpace in the virtual memory space 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// | : page boundary 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// [,]: MemoryRegion 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// - : fillment 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// = : data 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// |---[=|====|====|==]--| 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ^ ^ ^ ^ 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// | | | | 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// | r_start +r_len | 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// space.data +space.size 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// space.file_offset is the offset of the mapped file segment from the start of 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// the file. if the MemorySpace's type is ALLOCATED_ARRAY, the distances of 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// (space.data, r_start) and (r_len, space.size) are zero. 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMemoryRegion* MemoryArea::request(size_t pOffset, size_t pLength) 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Space* space = find(pOffset, pLength); 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == space) { 58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // not found 59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pFileHandle) { 60affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if m_pFileHandle is NULL, clients delegate us an universal Space and 61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // we never remove it. In that way, space can not be NULL. 6267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao unreachable(diag::err_out_of_range_region) << pOffset << pLength; 63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao space = Space::Create(*m_pFileHandle, pOffset, pLength); 666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_SpaceMap.insert(std::make_pair(Key(space->start(), space->size()), space)); 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // adjust r_start 70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang off_t distance = pOffset - space->start(); 71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang void* r_start = space->memory() + distance; 72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // now, we have a legal space to hold the new MemoryRegion 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return MemoryRegion::Create(r_start, pLength, *space); 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// release - release a MemoryRegion 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MemoryArea::release(MemoryRegion* pRegion) 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == pRegion) 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Space *space = pRegion->parent(); 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion::Destroy(pRegion); 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 == space->numOfRegions()) { 87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != m_pFileHandle) { 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if m_pFileHandle is NULL, clients delegate us an universal Space and 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // we never remove it. Otherwise, we have to synchronize and release 91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Space. 92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pFileHandle->isWritable()) { 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // synchronize writable space before we release it. 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Space::Sync(space, *m_pFileHandle); 95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::pair<SpaceMapType::iterator, SpaceMapType::iterator> range = 986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_SpaceMap.equal_range(Key(space->start(), space->size())); 996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines SpaceMapType::iterator it; 1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (it = range.first; it != range.second; ++it) { 1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (space == it->second) 1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_SpaceMap.erase(it); 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Space::Release(space, *m_pFileHandle); 1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != space); 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Space::Destroy(space); 109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// clear - release all MemoryRegions 114affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid MemoryArea::clear() 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == m_pFileHandle) 117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines SpaceMapType::iterator space, sEnd = m_SpaceMap.end(); 120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pFileHandle->isWritable()) { 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (space = m_SpaceMap.begin(); space != sEnd; ++space) { 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Space::Sync(space->second, *m_pFileHandle); 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Space::Release(space->second, *m_pFileHandle); 1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != space->second); 1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Space::Destroy(space->second); 126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else { 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (space = m_SpaceMap.begin(); space != sEnd; ++space) { 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Space::Release(space->second, *m_pFileHandle); 1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != space->second); 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Space::Destroy(space->second); 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_SpaceMap.clear(); 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===--------------------------------------------------------------------===// 140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// SpaceList methods 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===--------------------------------------------------------------------===// 142affc150dc44fab1911775a49636d0ce85333b634Zonr ChangSpace* MemoryArea::find(size_t pOffset, size_t pLength) 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::pair<SpaceMapType::iterator, SpaceMapType::iterator> range = 145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_SpaceMap.equal_range(Key(pOffset, pLength)); 146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SpaceMapType::iterator it; 147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (it = range.first; it != range.second; ++it) { 148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((it->second->start() <= pOffset) && 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ((pOffset + pLength) <= (it->second->start() + it->second->size()))) 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return it->second; 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return NULL; 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 155affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst Space* MemoryArea::find(size_t pOffset, size_t pLength) const 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::pair<SpaceMapType::const_iterator, SpaceMapType::const_iterator> range = 158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_SpaceMap.equal_range(Key(pOffset, pLength)); 159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SpaceMapType::const_iterator it; 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (it = range.first; it != range.second; ++it) { 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((it->second->start() <= pOffset) && 162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ((pOffset + pLength) <= (it->second->start() + it->second->size()))) 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return it->second; 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 168