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