16 #include "llvm/Config/config.h"
28 #include <sys/types.h>
29 #include <system_error>
30 #if !defined(_MSC_VER) && !defined(__MINGW32__)
46 bool RequiresNullTerminator) {
47 assert((!RequiresNullTerminator || BufEnd[0] == 0) &&
48 "Buffer is not null terminated!");
49 BufferStart = BufStart;
61 memcpy(Memory, Data.
data(), Data.
size());
62 Memory[Data.
size()] = 0;
66 struct NamedBufferAlloc {
68 NamedBufferAlloc(
const Twine &
Name) : Name(Name) {}
72 void *
operator new(
size_t N,
const NamedBufferAlloc &Alloc) {
74 StringRef NameRef = Alloc.Name.toStringRef(NameBuf);
76 char *Mem =
static_cast<char *
>(
operator new(
N + NameRef.
size() + 1));
85 MemoryBufferMem(
StringRef InputData,
bool RequiresNullTerminator) {
86 init(InputData.
begin(), InputData.
end(), RequiresNullTerminator);
91 void operator delete(
void *p) { ::operator
delete(p); }
93 StringRef getBufferIdentifier()
const override {
95 return StringRef(reinterpret_cast<const char *>(
this + 1));
98 BufferKind getBufferKind()
const override {
99 return MemoryBuffer_Malloc;
106 uint64_t
Offset,
bool RequiresNullTerminator,
bool IsVolatileSize);
108 std::unique_ptr<MemoryBuffer>
110 bool RequiresNullTerminator) {
111 auto *
Ret =
new (NamedBufferAlloc(BufferName))
112 MemoryBufferMem(InputData, RequiresNullTerminator);
113 return std::unique_ptr<MemoryBuffer>(
Ret);
116 std::unique_ptr<MemoryBuffer>
122 std::unique_ptr<MemoryBuffer>
124 std::unique_ptr<MemoryBuffer> Buf =
128 memcpy(const_cast<char*>(Buf->getBufferStart()), InputData.
data(),
133 std::unique_ptr<MemoryBuffer>
141 size_t AlignedStringLen =
142 alignTo(
sizeof(MemoryBufferMem) + NameRef.
size() + 1, 16);
143 size_t RealLen = AlignedStringLen + Size + 1;
144 char *Mem =
static_cast<char*
>(
operator new(RealLen, std::nothrow));
152 char *Buf = Mem + AlignedStringLen;
155 auto *
Ret =
new (Mem) MemoryBufferMem(
StringRef(Buf, Size),
true);
156 return std::unique_ptr<MemoryBuffer>(
Ret);
159 std::unique_ptr<MemoryBuffer>
164 memset(const_cast<char*>(SB->getBufferStart()), 0, Size);
170 bool RequiresNullTerminator) {
176 return getFile(Filename, FileSize, RequiresNullTerminator);
182 return getFileAux(FilePath, -1, MapSize, Offset,
false,
false);
197 static uint64_t getLegalMapOffset(uint64_t
Offset) {
201 static uint64_t getLegalMapSize(uint64_t Len, uint64_t
Offset) {
202 return Len + (Offset - getLegalMapOffset(Offset));
205 const char *getStart(uint64_t Len, uint64_t
Offset) {
206 return MFR.
const_data() + (Offset - getLegalMapOffset(Offset));
210 MemoryBufferMMapFile(
bool RequiresNullTerminator,
int FD, uint64_t Len,
211 uint64_t Offset, std::error_code &EC)
212 : MFR(FD, sys::fs::mapped_file_region::readonly,
213 getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) {
215 const char *Start = getStart(Len, Offset);
216 init(Start, Start + Len, RequiresNullTerminator);
222 void operator delete(
void *p) { ::operator
delete(p); }
224 StringRef getBufferIdentifier()
const override {
226 return StringRef(reinterpret_cast<const char *>(
this + 1));
229 BufferKind getBufferKind()
const override {
230 return MemoryBuffer_MMap;
237 const ssize_t ChunkSize = 4096*4;
243 ReadBytes =
read(FD, Buffer.
end(), ChunkSize);
244 if (ReadBytes == -1) {
245 if (errno == EINTR)
continue;
246 return std::error_code(errno, std::generic_category());
249 }
while (ReadBytes != 0);
257 bool RequiresNullTerminator,
bool IsVolatileSize) {
258 return getFileAux(Filename, FileSize, FileSize, 0,
259 RequiresNullTerminator, IsVolatileSize);
264 uint64_t MapSize, int64_t Offset,
bool RequiresNullTerminator,
265 bool IsVolatileSize);
269 uint64_t Offset,
bool RequiresNullTerminator,
bool IsVolatileSize) {
277 RequiresNullTerminator, IsVolatileSize);
286 bool RequiresNullTerminator,
288 bool IsVolatileSize) {
297 if (MapSize < 4 * 4096 || MapSize < (
unsigned)PageSize)
300 if (!RequiresNullTerminator)
308 if (FileSize ==
size_t(-1)) {
312 FileSize = Status.getSize();
317 size_t End = Offset + MapSize;
324 if ((FileSize & (PageSize -1)) == 0)
327 #if defined(__CYGWIN__)
331 if ((FileSize & (4096 - 1)) == 0)
340 uint64_t MapSize, int64_t Offset,
bool RequiresNullTerminator,
341 bool IsVolatileSize) {
345 if (MapSize == uint64_t(-1)) {
348 if (FileSize == uint64_t(-1)) {
362 FileSize = Status.getSize();
367 if (
shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator,
368 PageSize, IsVolatileSize)) {
370 std::unique_ptr<MemoryBuffer> Result(
371 new (NamedBufferAlloc(Filename))
372 MemoryBufferMMapFile(RequiresNullTerminator, FD, MapSize, Offset, EC));
374 return std::move(Result);
377 std::unique_ptr<MemoryBuffer> Buf =
385 char *BufPtr =
const_cast<char *
>(Buf->getBufferStart());
387 size_t BytesLeft = MapSize;
389 if (lseek(FD, Offset, SEEK_SET) == -1)
390 return std::error_code(errno, std::generic_category());
395 ssize_t NumRead = ::pread(FD, BufPtr, BytesLeft, MapSize-BytesLeft+Offset);
397 ssize_t NumRead =
::read(FD, BufPtr, BytesLeft);
403 return std::error_code(errno, std::generic_category());
406 memset(BufPtr, 0, BytesLeft);
409 BytesLeft -= NumRead;
413 return std::move(Buf);
418 bool RequiresNullTerminator,
bool IsVolatileSize) {
420 RequiresNullTerminator, IsVolatileSize);
426 assert(MapSize != uint64_t(-1));
MemoryBufferRef getMemBufferRef() const
void init(const char *BufStart, const char *BufEnd, bool RequiresNullTerminator)
init - Initialize this MemoryBuffer as a reference to externally allocated memory, memory that we know is already null terminated.
Represents either an error or a value T.
value_type read(const void *memory)
Read a value of a particular endianness from memory.
std::error_code openFileForRead(const Twine &Name, int &ResultFD, SmallVectorImpl< char > *RealPath=nullptr)
This class provides various memory handling functions that manipulate MemoryBlock instances...
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getMemoryBufferForStream(int FD, const Twine &BufferName)
This class represents a memory mapped file.
StringRef getBuffer() const
static std::unique_ptr< MemoryBuffer > getNewUninitMemBuffer(size_t Size, const Twine &BufferName="")
Allocate a new MemoryBuffer of the specified size that is not initialized.
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(int FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatileSize=false)
Given an already-open file descriptor, read the file and return a MemoryBuffer.
void reserve(size_type N)
static std::unique_ptr< MemoryBuffer > getNewMemBuffer(size_t Size, StringRef BufferName="")
Allocate a new zero-initialized MemoryBuffer of the specified size.
const char * const_data() const
Get a const view of the data.
static bool shouldUseMmap(int FD, size_t FileSize, size_t MapSize, off_t Offset, bool RequiresNullTerminator, int PageSize, bool IsVolatileSize)
file_status - Represents the result of a call to stat and friends.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize, uint64_t Offset, bool RequiresNullTerminator, bool IsVolatileSize)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset)
Map a subrange of the specified file as a MemoryBuffer.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::error_code make_error_code(BitcodeError E)
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096))
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
static void CopyStringRef(char *Memory, StringRef Data)
CopyStringRef - Copies contents of a StringRef into a block of memory and null-terminates it...
INITIALIZE_PASS(HexagonEarlyIfConversion,"hexagon-eif","Hexagon early if conversion", false, false) bool HexagonEarlyIfConversion MachineBasicBlock * SB
initializer< Ty > init(const Ty &Val)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
The instances of the Type class are immutable: once they are created, they are never changed...
static const unsigned End
static unsigned getPageSize()
StringRef getBuffer() const
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
std::error_code ChangeStdinToBinary()
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, bool IsVolatileSize)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void set_size(size_type N)
Set the array size to N, which the current array must have enough capacity for.
Provides a library for accessing information about this process and other processes on the operating ...
file_type
An enumeration for the file system's view of the type.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatileSize=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileAsStream(const Twine &Filename)
Read all of the specified file into a MemoryBuffer as a stream (i.e.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef getBufferIdentifier() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringRef - Represent a constant reference to a string, i.e.
std::error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFileSlice(int FD, const Twine &Filename, uint64_t MapSize, int64_t Offset)
Given an already-open file descriptor, map some slice of it into a MemoryBuffer.