137b74a387bb3993387029859c2d9d051c41c724eStephen Hines//===- FileOutputBuffer.cpp -----------------------------------------------===// 287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// 387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// The MCLinker Project 487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// 587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// This file is distributed under the University of Illinois Open Source 687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// License. See LICENSE.TXT for details. 787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// 887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileOutputBuffer.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileHandle.h" 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Path.h" 1287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 1487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1587f34658dec9097d987d254a990ea7f311bfc95fStephen HinesFileOutputBuffer::FileOutputBuffer(llvm::sys::fs::mapped_file_region* pRegion, 1687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FileHandle& pFileHandle) 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_pRegion(pRegion), m_FileHandle(pFileHandle) { 1887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 1987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2037b74a387bb3993387029859c2d9d051c41c724eStephen HinesFileOutputBuffer::~FileOutputBuffer() { 2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Unmap buffer, letting OS flush dirty pages to file on disk. 22a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines m_pRegion.reset(); 2387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 25a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesstd::error_code 26a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen HinesFileOutputBuffer::create(FileHandle& pFileHandle, 27a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines size_t pSize, 28a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines std::unique_ptr<FileOutputBuffer>& pResult) { 290dea6bc96bb52346737966839ac68644f7939f58Stephen Hines std::error_code ec; 30a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 31a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Resize the file before mapping the file region. 32a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ec = llvm::sys::fs::resize_file(pFileHandle.handler(), pSize); 33a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (ec) 34a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines return ec; 35a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::unique_ptr<llvm::sys::fs::mapped_file_region> mapped_file( 3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines new llvm::sys::fs::mapped_file_region(pFileHandle.handler(), 38a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines llvm::sys::fs::mapped_file_region::readwrite, pSize, 0, ec)); 390dea6bc96bb52346737966839ac68644f7939f58Stephen Hines if (ec) 400dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return ec; 4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pResult.reset(new FileOutputBuffer(mapped_file.get(), pFileHandle)); 4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pResult) 440dea6bc96bb52346737966839ac68644f7939f58Stephen Hines mapped_file.release(); 45a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 460dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return std::error_code(); 4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4937b74a387bb3993387029859c2d9d051c41c724eStephen HinesMemoryRegion FileOutputBuffer::request(size_t pOffset, size_t pLength) { 5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pOffset > getBufferSize() || (pOffset + pLength) > getBufferSize()) 5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return MemoryRegion(); 5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return MemoryRegion(getBufferStart() + pOffset, pLength); 5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 5537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesllvm::StringRef FileOutputBuffer::getPath() const { 5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return m_FileHandle.path().native(); 5787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 60