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/OwningPtr.h" 1611da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#include "llvm/ADT/SmallString.h" 175745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#include "llvm/Config/config.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" 24333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer#include "llvm/Support/system_error.h" 259bc406019ef8e8c682afc10c46a9c4d4d6840d42Jeff Cohen#include <cassert> 26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <cerrno> 27333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner#include <cstdio> 28333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner#include <cstring> 29476b242fe7a61e5f9ac6214b0bc5c680d24f152eNick Lewycky#include <new> 3011da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#include <sys/stat.h> 31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <sys/types.h> 3211da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#if !defined(_MSC_VER) && !defined(__MINGW32__) 3311da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#include <unistd.h> 3411da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#else 3511da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#include <io.h> 362f87fed2479017589051a5a99277e4278f6372e3Dan Gohman// Simplistic definitinos of these macros to allow files to be read with 372f87fed2479017589051a5a99277e4278f6372e3Dan Gohman// MapInFilePages. 382f87fed2479017589051a5a99277e4278f6372e3Dan Gohman#ifndef S_ISREG 392f87fed2479017589051a5a99277e4278f6372e3Dan Gohman#define S_ISREG(x) (1) 402f87fed2479017589051a5a99277e4278f6372e3Dan Gohman#endif 412f87fed2479017589051a5a99277e4278f6372e3Dan Gohman#ifndef S_ISBLK 422f87fed2479017589051a5a99277e4278f6372e3Dan Gohman#define S_ISBLK(x) (0) 4364afe13a2090d34e25d197862f4c3f54fcea6397Daniel Dunbar#endif 4411da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#endif 458811080a65f003127961b98a98d5474ddde6801aGabor Greif#include <fcntl.h> 46333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnerusing namespace llvm; 47333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 48333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 49333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// MemoryBuffer implementation itself. 50333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 51333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 52d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin KramerMemoryBuffer::~MemoryBuffer() { } 53333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 54333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// init - Initialize this MemoryBuffer as a reference to externally allocated 55333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// memory, memory that we know is already null terminated. 56f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindolavoid MemoryBuffer::init(const char *BufStart, const char *BufEnd, 57f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola bool RequiresNullTerminator) { 5849ab1207df3d7d5a4bb3b3e3dcc611e78d262714Rafael Espindola assert((!RequiresNullTerminator || BufEnd[0] == 0) && 59f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola "Buffer is not null terminated!"); 60333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner BufferStart = BufStart; 61333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner BufferEnd = BufEnd; 62333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 63333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 64333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 65333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// MemoryBufferMem implementation. 66333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 67333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 68d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer/// CopyStringRef - Copies contents of a StringRef into a block of memory and 69d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer/// null-terminates it. 70d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramerstatic void CopyStringRef(char *Memory, StringRef Data) { 71d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer memcpy(Memory, Data.data(), Data.size()); 72d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer Memory[Data.size()] = 0; // Null terminate string. 73d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer} 74d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 75cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencerstruct NamedBufferAlloc { 76cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer StringRef Name; 77cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer NamedBufferAlloc(StringRef Name) : Name(Name) {} 78cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer}; 79cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer 80cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencervoid *operator new(size_t N, const NamedBufferAlloc &Alloc) { 81cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer char *Mem = static_cast<char *>(operator new(N + Alloc.Name.size() + 1)); 82cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer CopyStringRef(Mem + N, Alloc.Name); 83cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return Mem; 84d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer} 85d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 86333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnernamespace { 87d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer/// MemoryBufferMem - Named MemoryBuffer pointing to a block of memory. 88333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnerclass MemoryBufferMem : public MemoryBuffer { 89333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnerpublic: 90f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola MemoryBufferMem(StringRef InputData, bool RequiresNullTerminator) { 91f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola init(InputData.begin(), InputData.end(), RequiresNullTerminator); 92333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner } 93d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 94a96a1824747632ce87ef065b4a13fb777d2b14d6Craig Topper virtual const char *getBufferIdentifier() const LLVM_OVERRIDE { 95d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // The name is stored after the class itself. 96d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer return reinterpret_cast<const char*>(this + 1); 97333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner } 98a96a1824747632ce87ef065b4a13fb777d2b14d6Craig Topper 99a96a1824747632ce87ef065b4a13fb777d2b14d6Craig Topper virtual BufferKind getBufferKind() const LLVM_OVERRIDE { 1005d86759e0ff44e07ead4982673fe10abec50f765Ted Kremenek return MemoryBuffer_Malloc; 1015d86759e0ff44e07ead4982673fe10abec50f765Ted Kremenek } 102333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner}; 103333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 104333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 105333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note 1069bb4a2ae8a0ce6404b9752f93ceebb2d00401997Chris Lattner/// that InputData must be a null terminated if RequiresNullTerminator is true! 1074c842dda3939c6b9f83ba7e8e19e43445cd9a832Chris LattnerMemoryBuffer *MemoryBuffer::getMemBuffer(StringRef InputData, 1089916d2ac3941513e301e39dee76a981c7caab694Rafael Espindola StringRef BufferName, 1099916d2ac3941513e301e39dee76a981c7caab694Rafael Espindola bool RequiresNullTerminator) { 110cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return new (NamedBufferAlloc(BufferName)) 111cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer MemoryBufferMem(InputData, RequiresNullTerminator); 112333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 113333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 1143daae2701b76293c31c1cbdafc9782352321e1f0Chris Lattner/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, 1153daae2701b76293c31c1cbdafc9782352321e1f0Chris Lattner/// copying the contents and taking ownership of it. This has no requirements 1163daae2701b76293c31c1cbdafc9782352321e1f0Chris Lattner/// on EndPtr[0]. 1174c842dda3939c6b9f83ba7e8e19e43445cd9a832Chris LattnerMemoryBuffer *MemoryBuffer::getMemBufferCopy(StringRef InputData, 118d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer StringRef BufferName) { 119d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer MemoryBuffer *Buf = getNewUninitMemBuffer(InputData.size(), BufferName); 120d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer if (!Buf) return 0; 121d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer memcpy(const_cast<char*>(Buf->getBufferStart()), InputData.data(), 122d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer InputData.size()); 123d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer return Buf; 1243daae2701b76293c31c1cbdafc9782352321e1f0Chris Lattner} 1253daae2701b76293c31c1cbdafc9782352321e1f0Chris Lattner 126333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size 127d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer/// that is not initialized. Note that the caller should initialize the 128d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer/// memory allocated by this method. The memory is owned by the MemoryBuffer 129d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer/// object. 13034cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan ChengMemoryBuffer *MemoryBuffer::getNewUninitMemBuffer(size_t Size, 131d65267ee625bb9cf8dc655a0c0409760e2b76c71Daniel Dunbar StringRef BufferName) { 132d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // Allocate space for the MemoryBuffer, the data and the name. It is important 133d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // that MemoryBuffer and data are aligned so PointerIntPair works with them. 134d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer size_t AlignedStringLen = 135d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer RoundUpToAlignment(sizeof(MemoryBufferMem) + BufferName.size() + 1, 136d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer sizeof(void*)); // TODO: Is sizeof(void*) enough? 137d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer size_t RealLen = AlignedStringLen + Size + 1; 138d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer char *Mem = static_cast<char*>(operator new(RealLen, std::nothrow)); 139d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer if (!Mem) return 0; 140d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 141d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // The name is stored after the class itself. 142d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer CopyStringRef(Mem + sizeof(MemoryBufferMem), BufferName); 143d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 144d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer // The buffer begins after the name and must be aligned. 145d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer char *Buf = Mem + AlignedStringLen; 146d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer Buf[Size] = 0; // Null terminate buffer. 147d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 148f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return new (Mem) MemoryBufferMem(StringRef(Buf, Size), true); 149333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 150333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 151333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that 152333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// is completely initialized to zeros. Note that the caller should 153333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// initialize the memory allocated by this method. The memory is owned by 154333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner/// the MemoryBuffer object. 155d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin KramerMemoryBuffer *MemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) { 156333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner MemoryBuffer *SB = getNewUninitMemBuffer(Size, BufferName); 157726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng if (!SB) return 0; 158d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer memset(const_cast<char*>(SB->getBufferStart()), 0, Size); 159333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner return SB; 160333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 161333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 162333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 1632b1f1066aca0f6a3687377636a86086fa2cd222dChris Lattner/// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin 1642b1f1066aca0f6a3687377636a86086fa2cd222dChris Lattner/// if the Filename is "-". If an error occurs, this returns null and fills 1652b1f1066aca0f6a3687377636a86086fa2cd222dChris Lattner/// in *ErrStr with a reason. If stdin is empty, this API (unlike getSTDIN) 1662b1f1066aca0f6a3687377636a86086fa2cd222dChris Lattner/// returns an empty buffer. 1673ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencererror_code MemoryBuffer::getFileOrSTDIN(StringRef Filename, 1683ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> &result, 1693ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer int64_t FileSize) { 170d65267ee625bb9cf8dc655a0c0409760e2b76c71Daniel Dunbar if (Filename == "-") 1713ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer return getSTDIN(result); 1723ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer return getFile(Filename, result, FileSize); 1732b1f1066aca0f6a3687377636a86086fa2cd222dChris Lattner} 1742b1f1066aca0f6a3687377636a86086fa2cd222dChris Lattner 1753ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencererror_code MemoryBuffer::getFileOrSTDIN(const char *Filename, 1763ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> &result, 1773ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer int64_t FileSize) { 17860e6f3d4123a01babeb2c1a0e00d0a2b109008e5Dan Gohman if (strcmp(Filename, "-") == 0) 1793ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer return getSTDIN(result); 1803ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer return getFile(Filename, result, FileSize); 18160e6f3d4123a01babeb2c1a0e00d0a2b109008e5Dan Gohman} 18260e6f3d4123a01babeb2c1a0e00d0a2b109008e5Dan Gohman 183333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 18411da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner// MemoryBuffer::getFile implementation. 185333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 186333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 187333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattnernamespace { 188cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer/// \brief Memorry maps a file descriptor using sys::fs::mapped_file_region. 189cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer/// 190cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer/// This handles converting the offset into a legal offset on the platform. 191cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencerclass MemoryBufferMMapFile : public MemoryBuffer { 192cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer sys::fs::mapped_file_region MFR; 193cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer 194cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer static uint64_t getLegalMapOffset(uint64_t Offset) { 195cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return Offset & ~(sys::fs::mapped_file_region::alignment() - 1); 196cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 197cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer 198cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer static uint64_t getLegalMapSize(uint64_t Len, uint64_t Offset) { 199cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return Len + (Offset - getLegalMapOffset(Offset)); 200cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 201d4d1f85aa751cadf69768746afd2c6c43c116ac2Benjamin Kramer 202cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer const char *getStart(uint64_t Len, uint64_t Offset) { 203cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return MFR.const_data() + (Offset - getLegalMapOffset(Offset)); 204cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 205f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 206cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencerpublic: 207cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len, 208cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer uint64_t Offset, error_code EC) 209cc3a595ab938352f3acf8652c5858ddf879524a5Michael J. Spencer : MFR(FD, false, sys::fs::mapped_file_region::readonly, 210cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) { 211cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer if (!EC) { 212cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer const char *Start = getStart(Len, Offset); 213cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer init(Start, Start + Len, RequiresNullTerminator); 214cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 215cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer } 216f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 217cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer virtual const char *getBufferIdentifier() const LLVM_OVERRIDE { 218cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer // The name is stored after the class itself. 219cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer return reinterpret_cast<const char *>(this + 1); 22011da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner } 221a96a1824747632ce87ef065b4a13fb777d2b14d6Craig Topper 222a96a1824747632ce87ef065b4a13fb777d2b14d6Craig Topper virtual BufferKind getBufferKind() const LLVM_OVERRIDE { 2235d86759e0ff44e07ead4982673fe10abec50f765Ted Kremenek return MemoryBuffer_MMap; 2245d86759e0ff44e07ead4982673fe10abec50f765Ted Kremenek } 225333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner}; 226333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 227333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 2287895353b758829647515a993a26dcfffa89727a8Daniel Dunbarstatic error_code getMemoryBufferForStream(int FD, 2297895353b758829647515a993a26dcfffa89727a8Daniel Dunbar StringRef BufferName, 2307895353b758829647515a993a26dcfffa89727a8Daniel Dunbar OwningPtr<MemoryBuffer> &result) { 2317895353b758829647515a993a26dcfffa89727a8Daniel Dunbar const ssize_t ChunkSize = 4096*4; 2327895353b758829647515a993a26dcfffa89727a8Daniel Dunbar SmallString<ChunkSize> Buffer; 2337895353b758829647515a993a26dcfffa89727a8Daniel Dunbar ssize_t ReadBytes; 2347895353b758829647515a993a26dcfffa89727a8Daniel Dunbar // Read into Buffer until we hit EOF. 2357895353b758829647515a993a26dcfffa89727a8Daniel Dunbar do { 2367895353b758829647515a993a26dcfffa89727a8Daniel Dunbar Buffer.reserve(Buffer.size() + ChunkSize); 2377895353b758829647515a993a26dcfffa89727a8Daniel Dunbar ReadBytes = read(FD, Buffer.end(), ChunkSize); 2387895353b758829647515a993a26dcfffa89727a8Daniel Dunbar if (ReadBytes == -1) { 2397895353b758829647515a993a26dcfffa89727a8Daniel Dunbar if (errno == EINTR) continue; 2407895353b758829647515a993a26dcfffa89727a8Daniel Dunbar return error_code(errno, posix_category()); 2417895353b758829647515a993a26dcfffa89727a8Daniel Dunbar } 2427895353b758829647515a993a26dcfffa89727a8Daniel Dunbar Buffer.set_size(Buffer.size() + ReadBytes); 2437895353b758829647515a993a26dcfffa89727a8Daniel Dunbar } while (ReadBytes != 0); 2447895353b758829647515a993a26dcfffa89727a8Daniel Dunbar 2457895353b758829647515a993a26dcfffa89727a8Daniel Dunbar result.reset(MemoryBuffer::getMemBufferCopy(Buffer, BufferName)); 2467895353b758829647515a993a26dcfffa89727a8Daniel Dunbar return error_code::success(); 2477895353b758829647515a993a26dcfffa89727a8Daniel Dunbar} 2487895353b758829647515a993a26dcfffa89727a8Daniel Dunbar 2493ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencererror_code MemoryBuffer::getFile(StringRef Filename, 2503ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> &result, 25111d1803770f54dad441007a6ebafc70cb9395695Rafael Espindola int64_t FileSize, 25211d1803770f54dad441007a6ebafc70cb9395695Rafael Espindola bool RequiresNullTerminator) { 2537cf705461cfdca5dd5b48a5065f8e24a1ce8c8c4Chris Lattner // Ensure the path is null terminated. 25460e6f3d4123a01babeb2c1a0e00d0a2b109008e5Dan Gohman SmallString<256> PathBuf(Filename.begin(), Filename.end()); 25511d1803770f54dad441007a6ebafc70cb9395695Rafael Espindola return MemoryBuffer::getFile(PathBuf.c_str(), result, FileSize, 25611d1803770f54dad441007a6ebafc70cb9395695Rafael Espindola RequiresNullTerminator); 25760e6f3d4123a01babeb2c1a0e00d0a2b109008e5Dan Gohman} 25860e6f3d4123a01babeb2c1a0e00d0a2b109008e5Dan Gohman 2593ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencererror_code MemoryBuffer::getFile(const char *Filename, 2603ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> &result, 26111d1803770f54dad441007a6ebafc70cb9395695Rafael Espindola int64_t FileSize, 26211d1803770f54dad441007a6ebafc70cb9395695Rafael Espindola bool RequiresNullTerminator) { 2633b05d9f4db3399f524fdf206a22771a87fa321b2Argyrios Kyrtzidis // FIXME: Review if this check is unnecessary on windows as well. 2643b05d9f4db3399f524fdf206a22771a87fa321b2Argyrios Kyrtzidis#ifdef LLVM_ON_WIN32 2653f85144a8958ef2365e7a145859a26f870ba8445Kaelyn Uhrain // First check that the "file" is not a directory 2663f85144a8958ef2365e7a145859a26f870ba8445Kaelyn Uhrain bool is_dir = false; 2673f85144a8958ef2365e7a145859a26f870ba8445Kaelyn Uhrain error_code err = sys::fs::is_directory(Filename, is_dir); 2683f85144a8958ef2365e7a145859a26f870ba8445Kaelyn Uhrain if (err) 2693f85144a8958ef2365e7a145859a26f870ba8445Kaelyn Uhrain return err; 2703aaa59bcbb226499cd4743a42e919d3bdc24aa42Kaelyn Uhrain if (is_dir) 2713f85144a8958ef2365e7a145859a26f870ba8445Kaelyn Uhrain return make_error_code(errc::is_a_directory); 2723b05d9f4db3399f524fdf206a22771a87fa321b2Argyrios Kyrtzidis#endif 2733f85144a8958ef2365e7a145859a26f870ba8445Kaelyn Uhrain 27460e6f3d4123a01babeb2c1a0e00d0a2b109008e5Dan Gohman int OpenFlags = O_RDONLY; 27511da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#ifdef O_BINARY 276a442006f4876be13b632ba1a4bee3ae827194eb1Bill Wendling OpenFlags |= O_BINARY; // Open input file in binary mode on win32. 27711da4cf25c3de590ecf434316973e9f25eec34c3Chris Lattner#endif 27860e6f3d4123a01babeb2c1a0e00d0a2b109008e5Dan Gohman int FD = ::open(Filename, OpenFlags); 2799bb4a2ae8a0ce6404b9752f93ceebb2d00401997Chris Lattner if (FD == -1) 2803ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer return error_code(errno, posix_category()); 2819bb4a2ae8a0ce6404b9752f93ceebb2d00401997Chris Lattner 28211d1803770f54dad441007a6ebafc70cb9395695Rafael Espindola error_code ret = getOpenFile(FD, Filename, result, FileSize, FileSize, 28311d1803770f54dad441007a6ebafc70cb9395695Rafael Espindola 0, RequiresNullTerminator); 284cc3a595ab938352f3acf8652c5858ddf879524a5Michael J. Spencer close(FD); 285b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola return ret; 2867cf705461cfdca5dd5b48a5065f8e24a1ce8c8c4Chris Lattner} 2871f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 2889d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindolastatic bool shouldUseMmap(int FD, 2899d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola size_t FileSize, 290f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola size_t MapSize, 291f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola off_t Offset, 292f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola bool RequiresNullTerminator, 293f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola int PageSize) { 294f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // We don't use mmap for small files because this can severely fragment our 295f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // address space. 296f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola if (MapSize < 4096*4) 297f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return false; 298f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 299f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola if (!RequiresNullTerminator) 300f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return true; 301f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 3029d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola 3039d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // If we don't know the file size, use fstat to find out. fstat on an open 3049d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // file descriptor is cheaper than stat on a random path. 3059d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // FIXME: this chunk of code is duplicated, but it avoids a fstat when 3069d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // RequiresNullTerminator = false and MapSize != -1. 3079d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola if (FileSize == size_t(-1)) { 3089d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola struct stat FileInfo; 3099d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // TODO: This should use fstat64 when available. 3109d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola if (fstat(FD, &FileInfo) == -1) { 3119d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola return error_code(errno, posix_category()); 3129d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola } 3139d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola FileSize = FileInfo.st_size; 3149d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola } 3159d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola 316f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // If we need a null terminator and the end of the map is inside the file, 317f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // we cannot use mmap. 318f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola size_t End = Offset + MapSize; 319f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola assert(End <= FileSize); 320f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola if (End != FileSize) 321f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return false; 322f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 323f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // Don't try to map files that are exactly a multiple of the system page size 324f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // if we need a null terminator. 325f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola if ((FileSize & (PageSize -1)) == 0) 326f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return false; 327f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 328f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return true; 329f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola} 330f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 3313ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencererror_code MemoryBuffer::getOpenFile(int FD, const char *Filename, 3323ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> &result, 33371280b55a3406c7dd4215449bf4a3ab216e78ffdIvan Krasin uint64_t FileSize, uint64_t MapSize, 33471280b55a3406c7dd4215449bf4a3ab216e78ffdIvan Krasin int64_t Offset, 335f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola bool RequiresNullTerminator) { 336f5867ab7178784bc63a3deafcf4fb09260e4d19aChandler Carruth static int PageSize = sys::process::get_self()->page_size(); 337f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 338f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola // Default is to map the full file. 33971280b55a3406c7dd4215449bf4a3ab216e78ffdIvan Krasin if (MapSize == uint64_t(-1)) { 3409d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // If we don't know the file size, use fstat to find out. fstat on an open 3419d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // file descriptor is cheaper than stat on a random path. 34271280b55a3406c7dd4215449bf4a3ab216e78ffdIvan Krasin if (FileSize == uint64_t(-1)) { 3439d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola struct stat FileInfo; 3449d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola // TODO: This should use fstat64 when available. 3459d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola if (fstat(FD, &FileInfo) == -1) { 3469d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola return error_code(errno, posix_category()); 3479d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola } 3487895353b758829647515a993a26dcfffa89727a8Daniel Dunbar 349a8eae3e35866329f2191a22a34421faa61448508Dan Gohman // If this not a file or a block device (e.g. it's a named pipe 350a8eae3e35866329f2191a22a34421faa61448508Dan Gohman // or character device), we can't trust the size. Create the memory 351a8eae3e35866329f2191a22a34421faa61448508Dan Gohman // buffer by copying off the stream. 352a8eae3e35866329f2191a22a34421faa61448508Dan Gohman if (!S_ISREG(FileInfo.st_mode) && !S_ISBLK(FileInfo.st_mode)) { 3537895353b758829647515a993a26dcfffa89727a8Daniel Dunbar return getMemoryBufferForStream(FD, Filename, result); 3547895353b758829647515a993a26dcfffa89727a8Daniel Dunbar } 3557895353b758829647515a993a26dcfffa89727a8Daniel Dunbar 3569d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola FileSize = FileInfo.st_size; 3579d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola } 358f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola MapSize = FileSize; 3599d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola } 360f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 3619d2234d6a0a5b2840427927ac971027aec0ddf63Rafael Espindola if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator, 362f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola PageSize)) { 363cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer error_code EC; 364cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer result.reset(new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile( 365cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer RequiresNullTerminator, FD, MapSize, Offset, EC)); 366cc189bfb08864ef615e5dc48476b992b81f29167Michael J. Spencer if (!EC) 36758604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie return error_code::success(); 36882e791dc420c399b7382a4754019b80466c898b0Chris Lattner } 369726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng 370f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola MemoryBuffer *Buf = MemoryBuffer::getNewUninitMemBuffer(MapSize, Filename); 371726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng if (!Buf) { 372333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer // Failed to create a buffer. The only way it can fail is if 373333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer // new(std::nothrow) returns 0. 3743ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer return make_error_code(errc::not_enough_memory); 375726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng } 376726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng 377726135ad1afe27af5f36a893eb55435b85d389a9Evan Cheng OwningPtr<MemoryBuffer> SB(Buf); 378333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner char *BufPtr = const_cast<char*>(SB->getBufferStart()); 3796a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer 380f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola size_t BytesLeft = MapSize; 3815745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#ifndef HAVE_PREAD 382f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola if (lseek(FD, Offset, SEEK_SET) == -1) 383f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola return error_code(errno, posix_category()); 3845745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#endif 385f7fdad15d910fc27bc9334faab5b71c101455e1aRafael Espindola 386333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner while (BytesLeft) { 3875745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#ifdef HAVE_PREAD 3885745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer ssize_t NumRead = ::pread(FD, BufPtr, BytesLeft, MapSize-BytesLeft+Offset); 3895745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#else 390333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner ssize_t NumRead = ::read(FD, BufPtr, BytesLeft); 3915745fbce1674b29f4dce6b6e31556c4c1e83dc89Benjamin Kramer#endif 3926a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer if (NumRead == -1) { 3936a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer if (errno == EINTR) 3946a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer continue; 3956a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer // Error while reading. 3963ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer return error_code(errno, posix_category()); 397333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner } 398b9153bacd05f4e31f8d841a54ee035abea5b3f41Argyrios Kyrtzidis if (NumRead == 0) { 399b9153bacd05f4e31f8d841a54ee035abea5b3f41Argyrios Kyrtzidis assert(0 && "We got inaccurate FileSize value or fstat reported an " 400b9153bacd05f4e31f8d841a54ee035abea5b3f41Argyrios Kyrtzidis "invalid file size."); 401541b2a4aa3401b1dcff9a127e0abeee08c5720f9Argyrios Kyrtzidis *BufPtr = '\0'; // null-terminate at the actual size. 402b9153bacd05f4e31f8d841a54ee035abea5b3f41Argyrios Kyrtzidis break; 403b9153bacd05f4e31f8d841a54ee035abea5b3f41Argyrios Kyrtzidis } 4046a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer BytesLeft -= NumRead; 4056a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer BufPtr += NumRead; 406333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner } 4076a9cd415495cd2422502fa2b84835409ce80d4deBenjamin Kramer 4083ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer result.swap(SB); 40958604cd944eec4a75046076cb53eb708aaf2ee09David Blaikie return error_code::success(); 410333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 411333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 412333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 413333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner// MemoryBuffer::getSTDIN implementation. 414333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner//===----------------------------------------------------------------------===// 415333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner 4163ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencererror_code MemoryBuffer::getSTDIN(OwningPtr<MemoryBuffer> &result) { 417333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner // Read in all of the data from stdin, we cannot mmap stdin. 418d65267ee625bb9cf8dc655a0c0409760e2b76c71Daniel Dunbar // 419d65267ee625bb9cf8dc655a0c0409760e2b76c71Daniel Dunbar // FIXME: That isn't necessarily true, we should try to mmap stdin and 420d65267ee625bb9cf8dc655a0c0409760e2b76c71Daniel Dunbar // fallback if it fails. 4210fea8ebb4a1e5b97d2413f45c0b5807d7eb5397eJeff Cohen sys::Program::ChangeStdinToBinary(); 4222372ccc111cd8d33553fb20116a449ba5df5f6e9Reid Spencer 4237895353b758829647515a993a26dcfffa89727a8Daniel Dunbar return getMemoryBufferForStream(0, "<stdin>", result); 424333ffd4abfcc3be32a945dc73c81adeafde1ba6bChris Lattner} 425