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