1333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===--- MemoryBuffer.cpp - Memory Buffer implementation ------------------===// 2333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// 3333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// The LLVM Compiler Infrastructure 4333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// 8333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 9333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// 10333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// This file implements the MemoryBuffer interface. 11333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// 12333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 13333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 14333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner#include "llvm/Support/MemoryBuffer.h" 1511da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#include "llvm/ADT/SmallString.h" 165745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#include "llvm/Config/config.h" 17c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/Errc.h" 181f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Errno.h" 193f85144a8958ef2365e7a145859a26f870ba8445Kaelyn Uhrain#include "llvm/Support/FileSystem.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/MathExtras.h" 211f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Path.h" 221f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Process.h" 231f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Program.h" 249bc406019ef8e8c682afc10c46a9c4d4d6840d42Jeff Cohen#include <cassert> 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <cerrno> 26333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner#include <cstring> 27476b242fe7a61e5f9ac6214b0bc5c680d24f152eNick Lewycky#include <new> 28d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <sys/types.h> 29c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error> 3011da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#if !defined(_MSC_VER) && !defined(__MINGW32__) 3111da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#include <unistd.h> 3211da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#else 3311da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#include <io.h> 3411da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#endif 35333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnerusing namespace llvm; 36333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 37333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 38333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// MemoryBuffer implementation itself. 39333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 40333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 41d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin KramerMemoryBuffer::~MemoryBuffer() { } 42333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 43333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// init - Initialize this MemoryBuffer as a reference to externally allocated 44333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// memory, memory that we know is already null terminated. 45f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindolavoid MemoryBuffer::init(const char *BufStart, const char *BufEnd, 46f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola bool RequiresNullTerminator) { 4749ab1207df3d7d5a4bb3b3e3dcc611e78d262714Rafael Espindola assert((!RequiresNullTerminator || BufEnd[0] == 0) && 48f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola "Buffer is not null terminated!"); 49333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner BufferStart = BufStart; 50333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner BufferEnd = BufEnd; 51333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 52333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 53333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 54333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// MemoryBufferMem implementation. 55333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 56333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 57d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer/// CopyStringRef - Copies contents of a StringRef into a block of memory and 58d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer/// null-terminates it. 59d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramerstatic void CopyStringRef(char *Memory, StringRef Data) { 60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!Data.empty()) 61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar memcpy(Memory, Data.data(), Data.size()); 62d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer Memory[Data.size()] = 0; // Null terminate string. 63d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer} 64d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 65ddcc82b871e2033ed3e566be8e7303aac5cde471Benjamin Kramernamespace { 66cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencerstruct NamedBufferAlloc { 6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const Twine &Name; 6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines NamedBufferAlloc(const Twine &Name) : Name(Name) {} 69cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer}; 70ddcc82b871e2033ed3e566be8e7303aac5cde471Benjamin Kramer} 71cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer 72cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencervoid *operator new(size_t N, const NamedBufferAlloc &Alloc) { 7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<256> NameBuf; 7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef NameRef = Alloc.Name.toStringRef(NameBuf); 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines char *Mem = static_cast<char *>(operator new(N + NameRef.size() + 1)); 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CopyStringRef(Mem + N, NameRef); 78cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return Mem; 79d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer} 80d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 81333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnernamespace { 82d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer/// MemoryBufferMem - Named MemoryBuffer pointing to a block of memory. 83333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnerclass MemoryBufferMem : public MemoryBuffer { 84333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnerpublic: 85f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola MemoryBufferMem(StringRef InputData, bool RequiresNullTerminator) { 86f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola init(InputData.begin(), InputData.end(), RequiresNullTerminator); 87333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner } 88d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 89de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// Disable sized deallocation for MemoryBufferMem, because it has 90de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// tail-allocated data. 91de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void operator delete(void *p) { ::operator delete(p); } 92de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getBufferIdentifier() const override { 94d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // The name is stored after the class itself. 95d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer return reinterpret_cast<const char*>(this + 1); 96333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner } 97a96a1824747632ce87ef065b4a13fb777d2b14d6Craig Topper 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BufferKind getBufferKind() const override { 995d86759e0ff44e07ead4982673fe10abec50f765Ted Kremenek return MemoryBuffer_Malloc; 1005d86759e0ff44e07ead4982673fe10abec50f765Ted Kremenek } 101333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner}; 102333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 103333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ErrorOr<std::unique_ptr<MemoryBuffer>> 10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize, 10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t Offset, bool RequiresNullTerminator, bool IsVolatileSize); 10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::unique_ptr<MemoryBuffer> 10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBuffer::getMemBuffer(StringRef InputData, StringRef BufferName, 11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool RequiresNullTerminator) { 11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *Ret = new (NamedBufferAlloc(BufferName)) 112cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer MemoryBufferMem(InputData, RequiresNullTerminator); 11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return std::unique_ptr<MemoryBuffer>(Ret); 11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::unique_ptr<MemoryBuffer> 11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBuffer::getMemBuffer(MemoryBufferRef Ref, bool RequiresNullTerminator) { 11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return std::unique_ptr<MemoryBuffer>(getMemBuffer( 11937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ref.getBuffer(), Ref.getBufferIdentifier(), RequiresNullTerminator)); 120333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 121333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 12237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::unique_ptr<MemoryBuffer> 12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBuffer::getMemBufferCopy(StringRef InputData, const Twine &BufferName) { 12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<MemoryBuffer> Buf = 12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines getNewUninitMemBuffer(InputData.size(), BufferName); 12637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Buf) 12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 128d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer memcpy(const_cast<char*>(Buf->getBufferStart()), InputData.data(), 129d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer InputData.size()); 130d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer return Buf; 1313daae2701b76293c31c1cbdafc9782352321e1f0Chris Lattner} 1323daae2701b76293c31c1cbdafc9782352321e1f0Chris Lattner 13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::unique_ptr<MemoryBuffer> 13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBuffer::getNewUninitMemBuffer(size_t Size, const Twine &BufferName) { 135d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // Allocate space for the MemoryBuffer, the data and the name. It is important 136d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // that MemoryBuffer and data are aligned so PointerIntPair works with them. 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // TODO: Is 16-byte alignment enough? We copy small object files with large 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // alignment expectations into this buffer. 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<256> NameBuf; 14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef NameRef = BufferName.toStringRef(NameBuf); 141d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer size_t AlignedStringLen = 142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar alignTo(sizeof(MemoryBufferMem) + NameRef.size() + 1, 16); 143d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer size_t RealLen = AlignedStringLen + Size + 1; 144d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer char *Mem = static_cast<char*>(operator new(RealLen, std::nothrow)); 14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Mem) 14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 147d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 148d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // The name is stored after the class itself. 14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CopyStringRef(Mem + sizeof(MemoryBufferMem), NameRef); 150d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 151d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // The buffer begins after the name and must be aligned. 152d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer char *Buf = Mem + AlignedStringLen; 153d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer Buf[Size] = 0; // Null terminate buffer. 154d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *Ret = new (Mem) MemoryBufferMem(StringRef(Buf, Size), true); 15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return std::unique_ptr<MemoryBuffer>(Ret); 157333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 158333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::unique_ptr<MemoryBuffer> 16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) { 16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<MemoryBuffer> SB = getNewUninitMemBuffer(Size, BufferName); 16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!SB) 16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 164d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer memset(const_cast<char*>(SB->getBufferStart()), 0, Size); 165333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner return SB; 166333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 167333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 168c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesErrorOr<std::unique_ptr<MemoryBuffer>> 169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarMemoryBuffer::getFileOrSTDIN(const Twine &Filename, int64_t FileSize, 170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool RequiresNullTerminator) { 17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<256> NameBuf; 17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef NameRef = Filename.toStringRef(NameBuf); 17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (NameRef == "-") 175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return getSTDIN(); 176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return getFile(Filename, FileSize, RequiresNullTerminator); 1772b1f1066aca0f6a3687377636a86086fa2cd222dChris Lattner} 1782b1f1066aca0f6a3687377636a86086fa2cd222dChris Lattner 17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesErrorOr<std::unique_ptr<MemoryBuffer>> 18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBuffer::getFileSlice(const Twine &FilePath, uint64_t MapSize, 18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t Offset) { 18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return getFileAux(FilePath, -1, MapSize, Offset, false, false); 18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 186333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 18711da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner// MemoryBuffer::getFile implementation. 188333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 189333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 190333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnernamespace { 191be5faa8a1ee2087712aa9006d392871a593c547aMatt Arsenault/// \brief Memory maps a file descriptor using sys::fs::mapped_file_region. 192cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer/// 193cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer/// This handles converting the offset into a legal offset on the platform. 194cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencerclass MemoryBufferMMapFile : public MemoryBuffer { 195cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer sys::fs::mapped_file_region MFR; 196cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer 197cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer static uint64_t getLegalMapOffset(uint64_t Offset) { 198cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return Offset & ~(sys::fs::mapped_file_region::alignment() - 1); 199cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 200cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer 201cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer static uint64_t getLegalMapSize(uint64_t Len, uint64_t Offset) { 202cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return Len + (Offset - getLegalMapOffset(Offset)); 203cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 204d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 205cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer const char *getStart(uint64_t Len, uint64_t Offset) { 206cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return MFR.const_data() + (Offset - getLegalMapOffset(Offset)); 207cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 208f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 209cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencerpublic: 210cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len, 211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint64_t Offset, std::error_code &EC) 212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : MFR(FD, sys::fs::mapped_file_region::readonly, 213cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) { 214cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer if (!EC) { 215cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer const char *Start = getStart(Len, Offset); 216cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer init(Start, Start + Len, RequiresNullTerminator); 217cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 218cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 219f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// Disable sized deallocation for MemoryBufferMMapFile, because it has 221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// tail-allocated data. 222de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void operator delete(void *p) { ::operator delete(p); } 223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getBufferIdentifier() const override { 225cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer // The name is stored after the class itself. 226cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return reinterpret_cast<const char *>(this + 1); 22711da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner } 228a96a1824747632ce87ef065b4a13fb777d2b14d6Craig Topper 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BufferKind getBufferKind() const override { 2305d86759e0ff44e07ead4982673fe10abec50f765Ted Kremenek return MemoryBuffer_MMap; 2315d86759e0ff44e07ead4982673fe10abec50f765Ted Kremenek } 232333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner}; 233333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 234333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 235c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic ErrorOr<std::unique_ptr<MemoryBuffer>> 23637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetMemoryBufferForStream(int FD, const Twine &BufferName) { 2377895353b758829647515a993a26dcfffa89727a8Daniel Dunbar const ssize_t ChunkSize = 4096*4; 2387895353b758829647515a993a26dcfffa89727a8Daniel Dunbar SmallString<ChunkSize> Buffer; 2397895353b758829647515a993a26dcfffa89727a8Daniel Dunbar ssize_t ReadBytes; 2407895353b758829647515a993a26dcfffa89727a8Daniel Dunbar // Read into Buffer until we hit EOF. 2417895353b758829647515a993a26dcfffa89727a8Daniel Dunbar do { 2427895353b758829647515a993a26dcfffa89727a8Daniel Dunbar Buffer.reserve(Buffer.size() + ChunkSize); 2437895353b758829647515a993a26dcfffa89727a8Daniel Dunbar ReadBytes = read(FD, Buffer.end(), ChunkSize); 2447895353b758829647515a993a26dcfffa89727a8Daniel Dunbar if (ReadBytes == -1) { 2457895353b758829647515a993a26dcfffa89727a8Daniel Dunbar if (errno == EINTR) continue; 246c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return std::error_code(errno, std::generic_category()); 2477895353b758829647515a993a26dcfffa89727a8Daniel Dunbar } 2487895353b758829647515a993a26dcfffa89727a8Daniel Dunbar Buffer.set_size(Buffer.size() + ReadBytes); 2497895353b758829647515a993a26dcfffa89727a8Daniel Dunbar } while (ReadBytes != 0); 2507895353b758829647515a993a26dcfffa89727a8Daniel Dunbar 25137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return MemoryBuffer::getMemBufferCopy(Buffer, BufferName); 2527895353b758829647515a993a26dcfffa89727a8Daniel Dunbar} 2537895353b758829647515a993a26dcfffa89727a8Daniel Dunbar 254c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 255c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesErrorOr<std::unique_ptr<MemoryBuffer>> 25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBuffer::getFile(const Twine &Filename, int64_t FileSize, 257c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool RequiresNullTerminator, bool IsVolatileSize) { 25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return getFileAux(Filename, FileSize, FileSize, 0, 25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RequiresNullTerminator, IsVolatileSize); 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 262c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic ErrorOr<std::unique_ptr<MemoryBuffer>> 26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, 264c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, 265c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool IsVolatileSize); 26670c7e485453fdbc228406715556f9447bc9f9fd8Rafael Espindola 267c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic ErrorOr<std::unique_ptr<MemoryBuffer>> 26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize, 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t Offset, bool RequiresNullTerminator, bool IsVolatileSize) { 270c1b49b56d4132efa2e06deb8f23508d0de4c8800Rafael Espindola int FD; 271c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::error_code EC = sys::fs::openFileForRead(Filename, FD); 272c1b49b56d4132efa2e06deb8f23508d0de4c8800Rafael Espindola if (EC) 273c1b49b56d4132efa2e06deb8f23508d0de4c8800Rafael Espindola return EC; 2749bb4a2ae8a0ce6404b9752f93ceebb2d00401997Chris Lattner 275c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> Ret = 27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines getOpenFileImpl(FD, Filename, FileSize, MapSize, Offset, 277c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines RequiresNullTerminator, IsVolatileSize); 278cc3a595ab938352f3acf8652c5858ddf879524a5Michael J. Spencer close(FD); 279c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return Ret; 2807cf705461cfdca5dd5b48a5065f8e24a1ce8c8c4Chris Lattner} 2811f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 2829d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindolastatic bool shouldUseMmap(int FD, 2839d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola size_t FileSize, 284f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola size_t MapSize, 285f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola off_t Offset, 286f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola bool RequiresNullTerminator, 287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines int PageSize, 288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsVolatileSize) { 289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // mmap may leave the buffer without null terminator if the file size changed 290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // by the time the last page is mapped in, so avoid it if the file size is 291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // likely to change. 292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IsVolatileSize) 293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 295f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // We don't use mmap for small files because this can severely fragment our 296f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // address space. 297378cd84adfe988166c3a45005043b506e3485c34NAKAMURA Takumi if (MapSize < 4 * 4096 || MapSize < (unsigned)PageSize) 298f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return false; 299f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 300f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola if (!RequiresNullTerminator) 301f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return true; 302f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 3039d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola 3049d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // If we don't know the file size, use fstat to find out. fstat on an open 3059d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // file descriptor is cheaper than stat on a random path. 3069d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // FIXME: this chunk of code is duplicated, but it avoids a fstat when 3079d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // RequiresNullTerminator = false and MapSize != -1. 3089d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola if (FileSize == size_t(-1)) { 3091ceefa6aa3fa82f7dda1ac070d133d3b1102bf93Rafael Espindola sys::fs::file_status Status; 310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (sys::fs::status(FD, Status)) 311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 3121ceefa6aa3fa82f7dda1ac070d133d3b1102bf93Rafael Espindola FileSize = Status.getSize(); 3139d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola } 3149d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola 315f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // If we need a null terminator and the end of the map is inside the file, 316f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // we cannot use mmap. 317f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola size_t End = Offset + MapSize; 318f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola assert(End <= FileSize); 319f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola if (End != FileSize) 320f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return false; 321f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 322f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // Don't try to map files that are exactly a multiple of the system page size 323f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // if we need a null terminator. 324f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola if ((FileSize & (PageSize -1)) == 0) 325f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return false; 326f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 32737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#if defined(__CYGWIN__) 32837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Don't try to map files that are exactly a multiple of the physical page size 32937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // if we need a null terminator. 33037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // FIXME: We should reorganize again getPageSize() on Win32. 33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((FileSize & (4096 - 1)) == 0) 33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 33337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif 33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 335f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return true; 336f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola} 337f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 338c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic ErrorOr<std::unique_ptr<MemoryBuffer>> 33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, 340c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, 341c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool IsVolatileSize) { 342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static int PageSize = sys::Process::getPageSize(); 343f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 344f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // Default is to map the full file. 34571280b55a3406c7dd4215449bf4a3ab216e78ffdIvan Krasin if (MapSize == uint64_t(-1)) { 3469d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // If we don't know the file size, use fstat to find out. fstat on an open 3479d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // file descriptor is cheaper than stat on a random path. 34871280b55a3406c7dd4215449bf4a3ab216e78ffdIvan Krasin if (FileSize == uint64_t(-1)) { 3491ceefa6aa3fa82f7dda1ac070d133d3b1102bf93Rafael Espindola sys::fs::file_status Status; 350c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::error_code EC = sys::fs::status(FD, Status); 3511ceefa6aa3fa82f7dda1ac070d133d3b1102bf93Rafael Espindola if (EC) 3521ceefa6aa3fa82f7dda1ac070d133d3b1102bf93Rafael Espindola return EC; 3537895353b758829647515a993a26dcfffa89727a8Daniel Dunbar 354a8eae3e35866329f2191a22a34421faa61448508Dan Gohman // If this not a file or a block device (e.g. it's a named pipe 355a8eae3e35866329f2191a22a34421faa61448508Dan Gohman // or character device), we can't trust the size. Create the memory 356a8eae3e35866329f2191a22a34421faa61448508Dan Gohman // buffer by copying off the stream. 3571ceefa6aa3fa82f7dda1ac070d133d3b1102bf93Rafael Espindola sys::fs::file_type Type = Status.type(); 3581ceefa6aa3fa82f7dda1ac070d133d3b1102bf93Rafael Espindola if (Type != sys::fs::file_type::regular_file && 3591ceefa6aa3fa82f7dda1ac070d133d3b1102bf93Rafael Espindola Type != sys::fs::file_type::block_file) 360c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return getMemoryBufferForStream(FD, Filename); 3617895353b758829647515a993a26dcfffa89727a8Daniel Dunbar 3621ceefa6aa3fa82f7dda1ac070d133d3b1102bf93Rafael Espindola FileSize = Status.getSize(); 3639d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola } 364f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola MapSize = FileSize; 3659d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola } 366f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 3679d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator, 368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines PageSize, IsVolatileSize)) { 369c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::error_code EC; 370c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::unique_ptr<MemoryBuffer> Result( 371c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines new (NamedBufferAlloc(Filename)) 372c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MemoryBufferMMapFile(RequiresNullTerminator, FD, MapSize, Offset, EC)); 373cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer if (!EC) 374c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return std::move(Result); 37582e791dc420c399b7382a4754019b80466c898b0Chris Lattner } 376726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng 37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<MemoryBuffer> Buf = 37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MemoryBuffer::getNewUninitMemBuffer(MapSize, Filename); 379726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng if (!Buf) { 380333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer // Failed to create a buffer. The only way it can fail is if 381333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer // new(std::nothrow) returns 0. 3823ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer return make_error_code(errc::not_enough_memory); 383726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng } 384726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng 38537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines char *BufPtr = const_cast<char *>(Buf->getBufferStart()); 3866a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer 387f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola size_t BytesLeft = MapSize; 3885745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#ifndef HAVE_PREAD 389f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola if (lseek(FD, Offset, SEEK_SET) == -1) 390c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return std::error_code(errno, std::generic_category()); 3915745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#endif 392f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 393333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner while (BytesLeft) { 3945745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#ifdef HAVE_PREAD 3955745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer ssize_t NumRead = ::pread(FD, BufPtr, BytesLeft, MapSize-BytesLeft+Offset); 3965745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#else 397333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner ssize_t NumRead = ::read(FD, BufPtr, BytesLeft); 3985745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#endif 3996a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer if (NumRead == -1) { 4006a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer if (errno == EINTR) 4016a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer continue; 4026a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer // Error while reading. 403c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return std::error_code(errno, std::generic_category()); 404333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner } 405b9153bacd05f4e31f8d841a54ee035abea5b3f41Argyrios Kyrtzidis if (NumRead == 0) { 406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines memset(BufPtr, 0, BytesLeft); // zero-initialize rest of the buffer. 407b9153bacd05f4e31f8d841a54ee035abea5b3f41Argyrios Kyrtzidis break; 408b9153bacd05f4e31f8d841a54ee035abea5b3f41Argyrios Kyrtzidis } 4096a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer BytesLeft -= NumRead; 4106a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer BufPtr += NumRead; 411333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner } 4126a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer 41337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return std::move(Buf); 414333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 415333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 416c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesErrorOr<std::unique_ptr<MemoryBuffer>> 41737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBuffer::getOpenFile(int FD, const Twine &Filename, uint64_t FileSize, 418c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool RequiresNullTerminator, bool IsVolatileSize) { 419c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return getOpenFileImpl(FD, Filename, FileSize, FileSize, 0, 420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RequiresNullTerminator, IsVolatileSize); 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 423c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesErrorOr<std::unique_ptr<MemoryBuffer>> 42437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBuffer::getOpenFileSlice(int FD, const Twine &Filename, uint64_t MapSize, 42537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int64_t Offset) { 42637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(MapSize != uint64_t(-1)); 427c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return getOpenFileImpl(FD, Filename, -1, MapSize, Offset, false, 42837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /*IsVolatileSize*/ false); 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 431c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getSTDIN() { 432333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner // Read in all of the data from stdin, we cannot mmap stdin. 433d65267ee625bb9cf8dc655a0c0409760e2b76c71Daniel Dunbar // 434d65267ee625bb9cf8dc655a0c0409760e2b76c71Daniel Dunbar // FIXME: That isn't necessarily true, we should try to mmap stdin and 435d65267ee625bb9cf8dc655a0c0409760e2b76c71Daniel Dunbar // fallback if it fails. 4369f1d9fd1964d82f3e801efb71518144492cdf290Rafael Espindola sys::ChangeStdinToBinary(); 4372372ccc111cd8d33553fb20116a449ba5df5f6e9Reid Spencer 438c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return getMemoryBufferForStream(0, "<stdin>"); 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 44037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 44137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMemoryBufferRef MemoryBuffer::getMemBufferRef() const { 44237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef Data = getBuffer(); 44337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef Identifier = getBufferIdentifier(); 44437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return MemoryBufferRef(Data, Identifier); 44537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 446