X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FStreamingMemoryObject.cpp;h=5a44e624eb8cff0b04ac70cacab10675f52af820;hb=fbf486927f3c127208c06cb500410efd6b291ee0;hp=7187ce013faf62d8c32812918f721411c74431fa;hpb=d0518569ecfe74ad7d90b26cee2d8ebebc1bdb93;p=oota-llvm.git diff --git a/lib/Support/StreamingMemoryObject.cpp b/lib/Support/StreamingMemoryObject.cpp index 7187ce013fa..5a44e624eb8 100644 --- a/lib/Support/StreamingMemoryObject.cpp +++ b/lib/Support/StreamingMemoryObject.cpp @@ -8,12 +8,9 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/StreamingMemoryObject.h" -#include "llvm/Support/Compiler.h" #include #include #include - - using namespace llvm; namespace { @@ -28,15 +25,12 @@ public: uint64_t getExtent() const override { return LastChar - FirstChar; } - int readBytes(uint64_t address, uint64_t size, - uint8_t *buf) const override; + uint64_t readBytes(uint8_t *Buf, uint64_t Size, + uint64_t Address) const override; const uint8_t *getPointer(uint64_t address, uint64_t size) const override; bool isValidAddress(uint64_t address) const override { return validAddress(address); } - bool isObjectEnd(uint64_t address) const override { - return objectEnd(address); - } private: const uint8_t* const FirstChar; @@ -47,20 +41,25 @@ private: bool validAddress(uint64_t address) const { return static_cast(address) < LastChar - FirstChar; } - bool objectEnd(uint64_t address) const { - return static_cast(address) == LastChar - FirstChar; - } - RawMemoryObject(const RawMemoryObject&) LLVM_DELETED_FUNCTION; - void operator=(const RawMemoryObject&) LLVM_DELETED_FUNCTION; + RawMemoryObject(const RawMemoryObject&) = delete; + void operator=(const RawMemoryObject&) = delete; }; -int RawMemoryObject::readBytes(uint64_t address, - uint64_t size, - uint8_t *buf) const { - if (!validAddress(address) || !validAddress(address + size - 1)) return -1; - memcpy(buf, (uint8_t *)(uintptr_t)(address + FirstChar), size); - return size; +uint64_t RawMemoryObject::readBytes(uint8_t *Buf, uint64_t Size, + uint64_t Address) const { + uint64_t BufferSize = LastChar - FirstChar; + if (Address >= BufferSize) + return 0; + + uint64_t End = Address + Size; + if (End > BufferSize) + End = BufferSize; + + assert(static_cast(End - Address) >= 0); + Size = End - Address; + memcpy(Buf, Address + FirstChar, Size); + return Size; } const uint8_t *RawMemoryObject::getPointer(uint64_t address, @@ -74,13 +73,7 @@ namespace llvm { // block until we actually want to read it. bool StreamingMemoryObject::isValidAddress(uint64_t address) const { if (ObjectSize && address < ObjectSize) return true; - return fetchToPos(address); -} - -bool StreamingMemoryObject::isObjectEnd(uint64_t address) const { - if (ObjectSize) return address == ObjectSize; - fetchToPos(address); - return address == ObjectSize && address != 0; + return fetchToPos(address); } uint64_t StreamingMemoryObject::getExtent() const { @@ -91,12 +84,24 @@ uint64_t StreamingMemoryObject::getExtent() const { return ObjectSize; } -int StreamingMemoryObject::readBytes(uint64_t address, - uint64_t size, - uint8_t *buf) const { - if (!fetchToPos(address + size - 1)) return -1; - memcpy(buf, &Bytes[address + BytesSkipped], size); - return 0; +uint64_t StreamingMemoryObject::readBytes(uint8_t *Buf, uint64_t Size, + uint64_t Address) const { + fetchToPos(Address + Size - 1); + // Note: For wrapped bitcode files will set ObjectSize after the + // first call to fetchToPos. In such cases, ObjectSize can be + // smaller than BytesRead. + size_t MaxAddress = + (ObjectSize && ObjectSize < BytesRead) ? ObjectSize : BytesRead; + if (Address >= MaxAddress) + return 0; + + uint64_t End = Address + Size; + if (End > MaxAddress) + End = MaxAddress; + assert(End >= Address); + Size = End - Address; + memcpy(Buf, &Bytes[Address + BytesSkipped], Size); + return Size; } bool StreamingMemoryObject::dropLeadingBytes(size_t s) { @@ -109,6 +114,8 @@ bool StreamingMemoryObject::dropLeadingBytes(size_t s) { void StreamingMemoryObject::setKnownObjectSize(size_t size) { ObjectSize = size; Bytes.reserve(size); + if (ObjectSize <= BytesRead) + EOFReached = true; } MemoryObject *getNonStreamedMemoryObject(const unsigned char *Start, @@ -116,9 +123,10 @@ MemoryObject *getNonStreamedMemoryObject(const unsigned char *Start, return new RawMemoryObject(Start, End); } -StreamingMemoryObject::StreamingMemoryObject(DataStreamer *streamer) : - Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0), - ObjectSize(0), EOFReached(false) { - BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize); +StreamingMemoryObject::StreamingMemoryObject( + std::unique_ptr Streamer) + : Bytes(kChunkSize), Streamer(std::move(Streamer)), BytesRead(0), + BytesSkipped(0), ObjectSize(0), EOFReached(false) { + BytesRead = this->Streamer->GetBytes(&Bytes[0], kChunkSize); } }