16 #include "llvm/Config/config.h" 29 #include <sys/types.h> 30 #include <system_error> 31 #if !defined(_MSC_VER) && !defined(__MINGW32__) 47 bool RequiresNullTerminator) {
48 assert((!RequiresNullTerminator || BufEnd[0] == 0) &&
49 "Buffer is not null terminated!");
50 BufferStart = BufStart;
63 Memory[Data.
size()] = 0;
67 struct NamedBufferAlloc {
69 NamedBufferAlloc(
const Twine &Name) :
Name(Name) {}
73 void *
operator new(
size_t N,
const NamedBufferAlloc &Alloc) {
75 StringRef NameRef = Alloc.Name.toStringRef(NameBuf);
77 char *Mem =
static_cast<char *
>(
operator new(
N + NameRef.
size() + 1));
85 class MemoryBufferMem :
public MB {
87 MemoryBufferMem(
StringRef InputData,
bool RequiresNullTerminator) {
89 RequiresNullTerminator);
94 void operator delete(
void *p) { ::operator
delete(p); }
98 return StringRef(reinterpret_cast<const char *>(
this + 1));
107 template <
typename MB>
112 std::unique_ptr<MemoryBuffer>
114 bool RequiresNullTerminator) {
115 auto *
Ret =
new (NamedBufferAlloc(BufferName))
116 MemoryBufferMem<MemoryBuffer>(InputData, RequiresNullTerminator);
117 return std::unique_ptr<MemoryBuffer>(
Ret);
120 std::unique_ptr<MemoryBuffer>
131 memcpy(Buf->getBufferStart(), InputData.
data(), InputData.
size());
132 return std::move(Buf);
135 std::unique_ptr<MemoryBuffer>
139 return std::move(*Buf);
145 bool RequiresNullTerminator) {
151 return getFile(Filename, FileSize, RequiresNullTerminator);
156 uint64_t
Offset,
bool IsVolatile) {
157 return getFileAux<MemoryBuffer>(FilePath, -1, MapSize,
Offset,
false,
169 template<
typename MB>
170 class MemoryBufferMMapFile :
public MB {
173 static uint64_t getLegalMapOffset(uint64_t
Offset) {
177 static uint64_t getLegalMapSize(uint64_t Len, uint64_t Offset) {
178 return Len + (Offset - getLegalMapOffset(Offset));
181 const char *getStart(uint64_t Len, uint64_t Offset) {
182 return MFR.
const_data() + (Offset - getLegalMapOffset(Offset));
186 MemoryBufferMMapFile(
bool RequiresNullTerminator,
int FD, uint64_t Len,
187 uint64_t Offset, std::error_code &EC)
188 : MFR(FD, MB::Mapmode, getLegalMapSize(Len, Offset),
189 getLegalMapOffset(Offset), EC) {
191 const char *Start = getStart(Len, Offset);
198 void operator delete(
void *p) { ::operator
delete(p); }
202 return StringRef(reinterpret_cast<const char *>(
this + 1));
213 const ssize_t ChunkSize = 4096*4;
221 return std::error_code(errno, std::generic_category());
223 }
while (ReadBytes != 0);
231 bool RequiresNullTerminator,
bool IsVolatile) {
232 return getFileAux<MemoryBuffer>(Filename, FileSize, FileSize, 0,
236 template <
typename MB>
239 uint64_t MapSize, int64_t
Offset,
bool RequiresNullTerminator,
242 template <
typename MB>
245 uint64_t
Offset,
bool RequiresNullTerminator,
bool IsVolatile) {
252 auto Ret = getOpenFileImpl<MB>(FD, Filename, FileSize, MapSize,
Offset,
261 return getFileAux<WritableMemoryBuffer>(Filename, FileSize, FileSize, 0,
268 uint64_t
Offset,
bool IsVolatile) {
269 return getFileAux<WritableMemoryBuffer>(Filename, -1, MapSize,
Offset,
false,
273 std::unique_ptr<WritableMemoryBuffer>
275 using MemBuffer = MemoryBufferMem<WritableMemoryBuffer>;
282 size_t AlignedStringLen =
alignTo(
sizeof(MemBuffer) + NameRef.
size() + 1, 16);
283 size_t RealLen = AlignedStringLen + Size + 1;
284 char *Mem =
static_cast<char*
>(
operator new(RealLen, std::nothrow));
292 char *Buf = Mem + AlignedStringLen;
295 auto *
Ret =
new (Mem) MemBuffer(
StringRef(Buf, Size),
true);
296 return std::unique_ptr<WritableMemoryBuffer>(
Ret);
299 std::unique_ptr<WritableMemoryBuffer>
312 bool RequiresNullTerminator,
323 if (MapSize < 4 * 4096 || MapSize < (
unsigned)PageSize)
326 if (!RequiresNullTerminator)
333 if (FileSize ==
size_t(-1)) {
342 size_t End = Offset + MapSize;
349 if ((FileSize & (PageSize -1)) == 0)
352 #if defined(__CYGWIN__) 356 if ((FileSize & (4096 - 1)) == 0)
374 if (MapSize == uint64_t(-1)) {
377 if (FileSize == uint64_t(-1)) {
395 std::unique_ptr<WriteThroughMemoryBuffer> Result(
396 new (NamedBufferAlloc(Filename))
397 MemoryBufferMMapFile<WriteThroughMemoryBuffer>(
false, FD, MapSize,
401 return std::move(Result);
416 template <
typename MB>
419 uint64_t MapSize, int64_t
Offset,
bool RequiresNullTerminator,
424 if (MapSize == uint64_t(-1)) {
427 if (FileSize == uint64_t(-1)) {
446 if (
shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator,
447 PageSize, IsVolatile)) {
449 std::unique_ptr<MB> Result(
450 new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile<MB>(
451 RequiresNullTerminator, FD, MapSize, Offset, EC));
453 return std::move(Result);
463 char *BufPtr = Buf.get()->getBufferStart();
465 size_t BytesLeft = MapSize;
467 if (lseek(FD, Offset, SEEK_SET) == -1)
468 return std::error_code(errno, std::generic_category());
474 MapSize - BytesLeft + Offset);
480 return std::error_code(errno, std::generic_category());
483 memset(BufPtr, 0, BytesLeft);
486 BytesLeft -= NumRead;
490 return std::move(Buf);
495 bool RequiresNullTerminator,
bool IsVolatile) {
496 return getOpenFileImpl<MemoryBuffer>(FD, Filename, FileSize, FileSize, 0,
502 int64_t
Offset,
bool IsVolatile) {
503 assert(MapSize != uint64_t(-1));
504 return getOpenFileImpl<MemoryBuffer>(FD, Filename, -1, MapSize,
Offset,
false,
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
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.
std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp, OpenFlags Flags, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFileSlice(int FD, const Twine &Filename, uint64_t MapSize, int64_t Offset, bool IsVolatile=false)
Given an already-open file descriptor, map some slice of it into a MemoryBuffer.
Represents either an error or a value T.
StringRef getBuffer() const
This class represents lattice values for constants.
std::error_code openFileForRead(const Twine &Name, int &ResultFD, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
constexpr char IsVolatile[]
Key for Kernel::Arg::Metadata::mIsVolatile.
static ErrorOr< std::unique_ptr< WritableMemoryBuffer > > getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset, bool IsVolatile=false)
Map a subrange of the specified file as a WritableMemoryBuffer.
This class provides various memory handling functions that manipulate MemoryBlock instances...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
This class represents a memory mapped file.
~SmallVectorMemoryBuffer() override
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...
void reserve(size_type N)
Represents the result of a call to sys::fs::status().
CD_OpenExisting - When opening a file:
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).
const char * const_data() const
Get a const view of the data.
virtual BufferKind getBufferKind() const =0
Return information on the memory mechanism used to support the MemoryBuffer.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
StringRef getBuffer() const
static ErrorOr< std::unique_ptr< MB > > getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, bool IsVolatile)
The access may reference the value stored in memory.
std::error_code make_error_code(BitcodeError E)
static ErrorOr< std::unique_ptr< WritableMemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool IsVolatile=false)
static ErrorOr< std::unique_ptr< WritableMemoryBuffer > > getMemoryBufferForStream(int FD, const Twine &BufferName)
static std::unique_ptr< WritableMemoryBuffer > getNewMemBuffer(size_t Size, const Twine &BufferName="")
Allocate a new zero-initialized MemoryBuffer of the specified size.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
static ErrorOr< std::unique_ptr< MB > > getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize, uint64_t Offset, bool RequiresNullTerminator, bool IsVolatile)
static void CopyStringRef(char *Memory, StringRef Data)
CopyStringRef - Copies contents of a StringRef into a block of memory and null-terminates it...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
static ErrorOr< std::unique_ptr< WriteThroughMemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1)
The instances of the Type class are immutable: once they are created, they are never changed...
static std::unique_ptr< WritableMemoryBuffer > getNewUninitMemBuffer(size_t Size, const Twine &BufferName="")
Allocate a new MemoryBuffer of the specified size that is not initialized.
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
auto RetryAfterSignal(const FailT &Fail, const Fun &F, const Args &... As) -> decltype(F(As...))
static unsigned getPageSize()
MemoryBufferRef getMemBufferRef() const
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...
static bool shouldUseMmap(int FD, size_t FileSize, size_t MapSize, off_t Offset, bool RequiresNullTerminator, int PageSize, bool IsVolatile)
StringRef getBufferIdentifier() const
std::error_code ChangeStdinToBinary()
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset, bool IsVolatile=false)
Map a subrange of the specified file as a MemoryBuffer.
static ErrorOr< std::unique_ptr< WriteThroughMemoryBuffer > > getReadWriteFile(const Twine &Filename, uint64_t FileSize, uint64_t MapSize, uint64_t Offset)
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 "-".
static ErrorOr< std::unique_ptr< WritableMemoryBuffer > > getMemBufferCopyImpl(StringRef InputData, const Twine &BufferName)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
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.
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileAsStream(const Twine &Filename)
Read all of the specified file into a MemoryBuffer as a stream (i.e.
BufferKind
The kind of memory backing used to support the MemoryBuffer.
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096), cl::Hidden)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void set_size(size_t Size)
Set the array size to N, which the current array must have enough capacity for.
static ErrorOr< std::unique_ptr< WriteThroughMemoryBuffer > > getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset)
Map a subrange of the specified file as a ReadWriteMemoryBuffer.
StringRef - Represent a constant reference to a string, i.e.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(int FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatile=false)
Given an already-open file descriptor, read the file and return a MemoryBuffer.