diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index 6258cecf7a8..05623fe8e71 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -341,7 +341,7 @@ public: // Read the next word from the stream. uint8_t Array[sizeof(word_t)] = {0}; - BitStream->getBitcodeBytes().readBytes(NextChar, sizeof(Array), Array); + BitStream->getBitcodeBytes().readBytes(Array, sizeof(Array), NextChar); // Handle big-endian byte-swapping if necessary. support::detail::packed_endian_specific_integral diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h index 584a2c55c04..f031a127ce6 100644 --- a/include/llvm/Support/MemoryObject.h +++ b/include/llvm/Support/MemoryObject.h @@ -36,18 +36,16 @@ public: virtual uint64_t getExtent() const = 0; /// Tries to read a contiguous range of bytes from the region, up to the end - /// of the region. You should override this function if there is a quicker way - /// than going back and forth with individual bytes. + /// of the region. /// /// @param address - The address of the first byte, in the same space as /// getBase(). /// @param size - The number of bytes to copy. /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL /// and large enough to hold size bytes. - /// @result - 0 if successful; -1 if not. Failure may be due to a - /// bounds violation or an implementation-specific error. - virtual int readBytes(uint64_t address, uint64_t size, - uint8_t *buf) const = 0; + /// @result - The number of bytes read. + virtual uint64_t readBytes(uint8_t *Buf, uint64_t Size, + uint64_t Address) const = 0; /// Ensures that the requested data is in memory, and returns a pointer to it. /// More efficient than using readBytes if the data is already in memory. May diff --git a/include/llvm/Support/StreamingMemoryObject.h b/include/llvm/Support/StreamingMemoryObject.h index da1b88738d0..39d1f4e9dd9 100644 --- a/include/llvm/Support/StreamingMemoryObject.h +++ b/include/llvm/Support/StreamingMemoryObject.h @@ -27,8 +27,8 @@ class StreamingMemoryObject : public MemoryObject { public: StreamingMemoryObject(DataStreamer *streamer); uint64_t getExtent() const override; - 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 { // This could be fixed by ensuring the bytes are fetched and making a copy, // requiring that the bitcode size be known, or otherwise ensuring that diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 713b6a3a4e5..b2ca22c74ba 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3430,7 +3430,7 @@ std::error_code BitcodeReader::InitLazyStream() { Stream.init(&*StreamFile); unsigned char buf[16]; - if (Bytes->readBytes(0, 16, buf) == -1) + if (Bytes->readBytes(buf, 16, 0) != 16) return Error(BitcodeError::InvalidBitcodeSignature); if (!isBitcode(buf, buf + 16)) diff --git a/lib/Support/StreamingMemoryObject.cpp b/lib/Support/StreamingMemoryObject.cpp index 7187ce013fa..8884a94181b 100644 --- a/lib/Support/StreamingMemoryObject.cpp +++ b/lib/Support/StreamingMemoryObject.cpp @@ -28,8 +28,8 @@ 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); @@ -55,12 +55,20 @@ private: void operator=(const RawMemoryObject&) LLVM_DELETED_FUNCTION; }; -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; + + Size = End - Address; + assert(Size >= 0); + memcpy(Buf, (uint8_t *)(Address + FirstChar), Size); + return Size; } const uint8_t *RawMemoryObject::getPointer(uint64_t address, @@ -91,12 +99,20 @@ 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); + uint64_t BufferSize = Bytes.size() - BytesSkipped; + if (Address >= BufferSize) + return 0; + + uint64_t End = Address + Size; + if (End > BufferSize) + End = BufferSize; + Size = End - Address; + assert(Size >= 0); + memcpy(Buf, &Bytes[Address + BytesSkipped], Size); + return Size; } bool StreamingMemoryObject::dropLeadingBytes(size_t s) {