StreamableMemoryObject.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //===- StreamableMemoryObject.cpp - Streamable data interface -------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/Support/StreamableMemoryObject.h"
  10. #include <cassert>
  11. #include <cstring>
  12. using namespace llvm;
  13. namespace {
  14. class RawMemoryObject : public StreamableMemoryObject {
  15. public:
  16. RawMemoryObject(const unsigned char *Start, const unsigned char *End) :
  17. FirstChar(Start), LastChar(End) {
  18. assert(LastChar > FirstChar && "Invalid start/end range");
  19. }
  20. virtual uint64_t getBase() const { return 0; }
  21. virtual uint64_t getExtent() const { return LastChar - FirstChar; }
  22. virtual int readByte(uint64_t address, uint8_t* ptr) const;
  23. virtual int readBytes(uint64_t address,
  24. uint64_t size,
  25. uint8_t* buf,
  26. uint64_t* copied) const;
  27. virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const;
  28. virtual bool isValidAddress(uint64_t address) const {
  29. return validAddress(address);
  30. }
  31. virtual bool isObjectEnd(uint64_t address) const {return objectEnd(address);}
  32. private:
  33. const uint8_t* const FirstChar;
  34. const uint8_t* const LastChar;
  35. // These are implemented as inline functions here to avoid multiple virtual
  36. // calls per public function
  37. bool validAddress(uint64_t address) const {
  38. return static_cast<ptrdiff_t>(address) < LastChar - FirstChar;
  39. }
  40. bool objectEnd(uint64_t address) const {
  41. return static_cast<ptrdiff_t>(address) == LastChar - FirstChar;
  42. }
  43. RawMemoryObject(const RawMemoryObject&); // DO NOT IMPLEMENT
  44. void operator=(const RawMemoryObject&); // DO NOT IMPLEMENT
  45. };
  46. int RawMemoryObject::readByte(uint64_t address, uint8_t* ptr) const {
  47. if (!validAddress(address)) return -1;
  48. *ptr = *((uint8_t *)(uintptr_t)(address + FirstChar));
  49. return 0;
  50. }
  51. int RawMemoryObject::readBytes(uint64_t address,
  52. uint64_t size,
  53. uint8_t* buf,
  54. uint64_t* copied) const {
  55. if (!validAddress(address) || !validAddress(address + size - 1)) return -1;
  56. memcpy(buf, (uint8_t *)(uintptr_t)(address + FirstChar), size);
  57. if (copied) *copied = size;
  58. return size;
  59. }
  60. const uint8_t *RawMemoryObject::getPointer(uint64_t address,
  61. uint64_t size) const {
  62. return FirstChar + address;
  63. }
  64. } // anonymous namespace
  65. namespace llvm {
  66. // If the bitcode has a header, then its size is known, and we don't have to
  67. // block until we actually want to read it.
  68. bool StreamingMemoryObject::isValidAddress(uint64_t address) const {
  69. if (ObjectSize && address < ObjectSize) return true;
  70. return fetchToPos(address);
  71. }
  72. bool StreamingMemoryObject::isObjectEnd(uint64_t address) const {
  73. if (ObjectSize) return address == ObjectSize;
  74. fetchToPos(address);
  75. return address == ObjectSize && address != 0;
  76. }
  77. uint64_t StreamingMemoryObject::getExtent() const {
  78. if (ObjectSize) return ObjectSize;
  79. size_t pos = BytesRead + kChunkSize;
  80. // keep fetching until we run out of bytes
  81. while (fetchToPos(pos)) pos += kChunkSize;
  82. return ObjectSize;
  83. }
  84. int StreamingMemoryObject::readByte(uint64_t address, uint8_t* ptr) const {
  85. if (!fetchToPos(address)) return -1;
  86. *ptr = Bytes[address + BytesSkipped];
  87. return 0;
  88. }
  89. int StreamingMemoryObject::readBytes(uint64_t address,
  90. uint64_t size,
  91. uint8_t* buf,
  92. uint64_t* copied) const {
  93. if (!fetchToPos(address + size - 1)) return -1;
  94. memcpy(buf, &Bytes[address + BytesSkipped], size);
  95. if (copied) *copied = size;
  96. return 0;
  97. }
  98. bool StreamingMemoryObject::dropLeadingBytes(size_t s) {
  99. if (BytesRead < s) return true;
  100. BytesSkipped = s;
  101. BytesRead -= s;
  102. return false;
  103. }
  104. void StreamingMemoryObject::setKnownObjectSize(size_t size) {
  105. ObjectSize = size;
  106. Bytes.reserve(size);
  107. }
  108. StreamableMemoryObject *getNonStreamedMemoryObject(
  109. const unsigned char *Start, const unsigned char *End) {
  110. return new RawMemoryObject(Start, End);
  111. }
  112. StreamableMemoryObject::~StreamableMemoryObject() { }
  113. StreamingMemoryObject::StreamingMemoryObject(DataStreamer *streamer) :
  114. Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0),
  115. ObjectSize(0), EOFReached(false) {
  116. BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize);
  117. }
  118. }