38template <
bool _Physical>
59template <
typename _Tp,
bool _Physical,
bool _Array,
typename _Enable =
void>
70template <
typename _Tp,
bool _Physical>
75template <
typename _Tp,
bool _Physical>
84template <
typename _Tp,
typename _PtrType,
bool _Physical,
typename _Enabled>
86 std::conditional_t<std::is_pointer_v<std::remove_extent_t<_Tp>>,
87 _PtrType, std::remove_all_extents_t<_Tp>>,
88 _Physical, std::is_array_v<_Tp>> {
91 using basic_type =
typename std::remove_pointer_t<std::remove_extent_t<_Tp>>;
94 using ref_type =
typename std::add_lvalue_reference_t<basic_type>;
97 static constexpr bool _is_pointer_v = std::is_pointer_v<array_element_type>;
99 std::is_pointer_v<std::remove_pointer_t<array_element_type>>;
100 static constexpr bool _is_void_v = std::is_void_v<basic_type>;
110 static_assert(!std::is_array_v<std::remove_extent_t<_Tp>>,
111 "Multidimensional arrays are not allowed");
112 static_assert(!std::is_reference_v<basic_type>,
"Reference types are not allowed");
114 "_PtrType must be specified for nested pointers");
115 static_assert(
_is_void_v || std::is_pod_v<_Tp>,
116 "guest_ptr types must be plain old data or void");
120 static_assert(!std::is_pointer_v<_PtrType>,
"_PtrType must be uint32_t, uint64_t, or "
126 return this->ptr_.address();
135 static_assert(!_Physical,
"page_directory() is only valid for virtual addresses");
137 return this->ptr_.page_directory();
147 return this->ptr_.domain();
154 static_assert(
_is_array_v,
"length() is only valid on array types");
156 return this->ptr_.length();
158 return this->length_;
161 inline decltype(
auto)
operator[](
size_t index)
const {
162 static_assert(
_is_array_v,
"operator[] is only valid on arrays");
164 return this->
at(index);
168 inline decltype(
auto)
operator*()
const {
188 inline decltype(
auto) _get_size_t_ptr(
size_t index)
const {
190 "_get_size_t_ptr(size_t) should only be called for _is_guest_ptr_t_v");
197 result._domain(&(this->ptr_.domain()));
198 result._mapping(this->ptr_._mapping());
199 if constexpr (!_Physical) {
200 result._page_directory(this->ptr_.page_directory());
204 result.reset(this->ptr_[index]);
206 result.reset(*this->ptr_);
212 inline decltype(
auto) _get_non_size_t_ptr(
size_t index)
const {
214 "_get_ptr(size_t) should only be called for _is_non_guest_ptr_t_v");
221 result.domain_ = this->
domain_;
223 if constexpr (!_Physical) {
230 introvirt_assert(index < this->length_,
"Tried to access array out of bounds");
232 result.reset(this->
buffer_[index]);
237 inline auto _get_ptr(
size_t index)
const {
239 return this->_get_size_t_ptr(index);
241 return this->_get_non_size_t_ptr(index);
256 inline decltype(
auto)
at(
size_t index)
const {
258 static_assert(
_is_array_v,
"at() is only valid on arrays");
262 return _get_ptr(index);
266 introvirt_assert(index < this->length_,
"Tried to access array out of bounds");
274 typename std::enable_if_t<!std::is_void_v<U> && !std::is_pointer_v<U>>* dummy =
nullptr>
275 inline void set(type value)
const {
278 static_assert(!
_is_array_v,
"set() requires an index for arrays");
284 typename std::enable_if_t<!std::is_void_v<U> && !std::is_pointer_v<U>>* dummy =
nullptr>
285 inline void set(
size_t index, type value)
const {
288 static_assert(
_is_array_v,
"set(index, value) is only valid on arrays");
290 introvirt_assert(index < this->length_,
"Tried to access array out of bounds");
293 template <
typename U =
array_element_type,
typename PtrType = _PtrType,
typename InTp,
294 typename InPtrType,
typename std::enable_if_t<std::is_pointer_v<U>>* dummy =
nullptr>
298 static_assert(!
_is_array_v,
"index must be provided for non-arrays");
307 template <
typename U =
array_element_type,
typename PtrType = _PtrType,
typename InTp,
308 typename InPtrType,
typename std::enable_if_t<std::is_pointer_v<U>>* dummy =
nullptr>
312 static_assert(
_is_array_v,
"set(index, ptrval) is only valid on arrays");
316 this->ptr_.set(index, in.
address());
323 template <
typename U = _Tp,
typename std::enable_if_t<!std::is_
void_v<U> &&
324 !std::is_po
inter_v<U>>* dummy =
nullptr>
331 template <
typename U = _Tp,
typename std::enable_if_t<!std::is_po
inter_v<U>>* dummy =
nullptr>
333 static_assert(
_is_array_v,
"begin() is only valid on array types");
336 template <
typename U = _Tp,
typename std::enable_if_t<!std::is_po
inter_v<U>>* dummy =
nullptr>
338 static_assert(
_is_array_v,
"end() is only valid on array types");
339 return this->
buffer_ + this->length_;
351 if constexpr (_Physical ==
false) {
366 template <
bool Physical = _Physical,
typename InPtrType,
367 typename std::enable_if_t<Physical>* dummy =
nullptr>
372 "Only void or 1-byte conversions from virtual to physical are supported");
380 typename std::enable_if_t<is_guest_ptr_t_v>* dummy =
nullptr>
382 this->ptr_.reset(x64, std::forward<Arguments>(args)...);
385 typename std::enable_if_t<is_guest_ptr_t_v>* dummy =
nullptr>
386 void reset(
bool x64, Arguments&&... args) {
387 this->ptr_.reset(x64, std::forward<Arguments>(args)...);
393 typename std::enable_if_t<!is_array && _Physical>* dummy =
nullptr>
399 typename std::enable_if_t<!is_array && _Physical>* dummy =
nullptr>
401 if (this->
domain_ != &domain) {
409 typename =
typename std::enable_if_t<is_array && _Physical>>
415 typename =
typename std::enable_if_t<is_array && _Physical>>
417 if (this->
domain_ != &domain) {
427 typename std::enable_if_t<!is_array && !_Physical>* dummy =
nullptr>
434 typename std::enable_if_t<!is_array && !_Physical>* dummy =
nullptr>
445 typename std::enable_if_t<is_array && !_Physical>* dummy =
nullptr>
453 typename std::enable_if_t<is_array && !_Physical>* dummy =
nullptr>
467 static_assert(!
_is_array_v,
"reset() requires a length for arrays");
468 if constexpr (_Physical) {
479 static_assert(
_is_array_v,
"reset() only requires a length for arrays");
480 if constexpr (_Physical) {
490 static_assert(!
_is_array_v,
"reset() requires a length for arrays");
493 if constexpr (_Physical ==
false) {
501 static_assert(
_is_array_v,
"reset() only requires a length for arrays");
504 if constexpr (_Physical ==
false) {
513 template <
typename Tp,
typename PtrType>
519 template <
typename Tp,
typename PtrType>
520 basic_guest_ptr<_Tp, _PtrType, _Physical, _Enabled>(
522 const basic_guest_ptr<Tp, PtrType, _Physical>& in,
size_t length) {
523 static_assert(
_is_array_v,
"length parameter is only valid for arrays");
526 template <
typename Tp,
typename PtrType>
527 basic_guest_ptr<_Tp, _PtrType, _Physical, _Enabled>&
532 template <
typename Tp,
typename PtrType>
536 template <
typename Tp,
typename PtrType>
541 template <
typename Tp,
typename PtrType>
545 this->_move(std::move(in));
547 template <
typename Tp,
typename PtrType>
548 basic_guest_ptr<_Tp, _PtrType, _Physical, _Enabled>(
549 basic_guest_ptr<Tp, PtrType, _Physical>&& in,
size_t length) {
551 static_assert(
_is_array_v,
"length parameter is only valid for arrays");
552 this->_move(std::move(in),
length);
554 template <
typename Tp,
typename PtrType>
555 basic_guest_ptr<_Tp, _PtrType, _Physical, _Enabled>&
557 this->_move(std::move(in));
560 template <
typename Tp,
typename PtrType>
562 this->_move(std::move(in));
564 template <
typename Tp,
typename PtrType>
566 this->_move(std::move(in),
length);
598 template <
typename I>
601 this->ptr_ += offset;
605 this->
_reset(this->
address_ + (offset * _element_size()), this->length_);
613 template <
typename I>
629 template <
typename I>
632 this->ptr_ -= offset;
636 this->
_reset(this->
address_ - (offset * _element_size()), this->length_);
644 template <
typename I>
653 template <
typename Tp,
typename PtrType>
656 using NormalTp1 = std::remove_const_t<_Tp>;
657 using NormalTp2 = std::remove_const_t<Tp>;
658 static_assert(std::is_same_v<NormalTp1, NormalTp2>,
659 "Pointers must be of the same type for subtraction");
665 explicit inline operator bool()
const {
667 return this->ptr_.operator bool();
686 if constexpr (_Physical ==
false) {
694 return !(*
this == in);
698 template <
typename U = std::remove_const_t<basic_type>,
699 typename std::enable_if_t<_is_array_v && std::is_same_v<U,
char>>* dummy =
nullptr>
700 operator std::string_view()
const {
703 template <
typename U = std::remove_const_t<basic_type>,
704 typename std::enable_if_t<std::is_same_v<U,
char>>* dummy =
nullptr>
705 std::string_view
str()
const {
706 static_assert(
_is_array_v,
"str() is only valid on char[]");
707 return std::string_view(this->
buffer_, this->length_);
712 typename U = std::remove_const_t<basic_type>,
713 typename std::enable_if_t<_is_array_v && std::is_same_v<U, char16_t>>* dummy =
nullptr>
714 operator std::u16string_view()
const {
717 template <
typename U = std::remove_const_t<basic_type>,
718 typename std::enable_if_t<std::is_same_v<U,
char16_t>>* dummy =
nullptr>
719 std::u16string_view
wstr()
const {
720 static_assert(
_is_array_v,
"wstr() is only valid on char16_t[]");
721 return std::u16string_view(this->
buffer_, this->length_);
723 template <
typename U = std::remove_const_t<basic_type>,
724 typename std::enable_if_t<std::is_same_v<U,
char16_t>>* dummy =
nullptr>
726 static_assert(
_is_array_v,
"str() is only valid on char16_t[]");
731 template <
typename U = std::remove_const_t<_Tp>,
732 typename std::enable_if_t<(!std::is_same_v<U,
char[]> &&
733 !std::is_same_v<U,
char16_t[]>)>* dummy =
nullptr>
740 template <
typename U = std::remove_const_t<_Tp>,
741 typename std::enable_if_t<(std::is_same_v<U,
char[]> ||
742 std::is_same_v<U,
char16_t[]>)>* dummy =
nullptr>
751 char*
const buf =
reinterpret_cast<char*
>(this->
mapping_->get());
752 const size_t buf_offset = this->
address_ & ~PageDirectory::PAGE_MASK;
754 this->
buffer_ =
reinterpret_cast<_PtrType*
>(buf + buf_offset);
764 template <
bool Physical = _Physical,
typename std::enable_if_t<Physical>* dummy =
nullptr>
767 const uint64_t buffer_length = this->_buffer_length();
769 const uint64_t last_pfn = (this->
address_ + buffer_length - 1) >> PageDirectory::PAGE_SHIFT;
770 const int page_count = (last_pfn - first_pfn) + 1;
772 uint64_t pfns[page_count];
776 for (
int i = 0; i < page_count; ++i) {
786 template <
bool Physical = _Physical,
typename std::enable_if_t<!Physical>* dummy =
nullptr>
789 const uint64_t buffer_length = this->_buffer_length();
791 const uint64_t last_pfn = (this->
address_ + buffer_length - 1) >> PageDirectory::PAGE_SHIFT;
792 const int page_count = (last_pfn - first_pfn) + 1;
794 uint64_t pfns[page_count];
797 uint64_t va = this->
address_ & PageDirectory::PAGE_MASK;
798 for (
int i = 0; i < page_count; ++i) {
801 const uint64_t pfn = pa >> PageDirectory::PAGE_SHIFT;
803 va += PageDirectory::PAGE_SIZE;
836 const uint64_t old_pfn = this->
address_ >> PageDirectory::PAGE_SHIFT;
837 const uint64_t new_pfn =
address >> PageDirectory::PAGE_SHIFT;
838 if (old_pfn == new_pfn) {
877 if constexpr (!_Physical) {
879 "Operation performed with null page directory");
882 introvirt_assert(this->length_,
"Operation performed with zero length array");
889 inline size_t _buffer_length()
const {
891 return this->_buffer_length(this->length_);
893 return _element_size();
898 inline size_t _buffer_length(
size_t length)
const {
899 if constexpr (std::is_void_v<_Tp>) {
902 return _element_size() *
length;
904 return _element_size();
908 constexpr size_t _element_size()
const {
911 if (this->ptr_.x64()) {
912 return sizeof(uint64_t);
914 return sizeof(uint32_t);
917 return sizeof(_PtrType);
918 }
else if constexpr (std::is_void_v<_Tp>) {
926 template <
typename InTp,
typename InPtrType,
bool InPhysical>
927 void _copy_base(
const basic_guest_ptr<InTp, InPtrType, InPhysical>& in,
size_t length = 0) {
929 using MyType = std::remove_const_t<std::remove_extent_t<_Tp>>;
930 using InType = std::remove_const_t<std::remove_extent_t<InTp>>;
931 constexpr bool is_array = std::is_array_v<InTp>;
934 static_assert(std::is_same_v<MyType, InType> || std::is_void_v<_Tp> || std::is_void_v<InTp>,
935 "Constructing from incompatible type");
937 static_assert(!std::is_const_v<InTp> || std::is_const_v<_Tp>,
938 "Constructing would disregard const qualifiers");
940 static_assert(!(!_Physical && InPhysical),
"Cannot convert from physical to virtual");
949 this->
domain_ = &(in.domain());
950 if constexpr (_Physical && !InPhysical) {
961 if constexpr (!_Physical) {
969 this->
_reset(in.address(), in.length());
979 this->
_reset(in.address());
984 template <
typename InTp,
typename InPtrType>
985 void _copy_from_guest_ptr_t_base(
const basic_guest_ptr<InTp, InPtrType, _Physical>& in,
988 static_assert(std::is_void_v<InPtrType> || std::is_same_v<InPtrType, uint32_t> ||
989 std::is_same_v<InPtrType, uint64_t>,
990 "InPtrType must be uint32_t or uint64_t");
993 using MyType = std::remove_const_t<std::remove_extent_t<_Tp>>;
994 using InType = std::remove_const_t<std::remove_extent_t<InTp>>;
995 constexpr bool is_array = std::is_array_v<InTp>;
998 static_assert(std::is_same_v<MyType, InType> || std::is_void_v<_Tp> || std::is_void_v<InTp>,
999 "Constructing from incompatible type");
1002 static_assert(!std::is_const_v<InTp> || std::is_const_v<_Tp>,
1003 "Constructing would disregard const qualifiers");
1005 static constexpr bool x64 = std::is_same_v<InPtrType, uint64_t>;
1006 this->ptr_.reset(x64);
1007 this->ptr_._domain(&(in.domain()));
1008 this->ptr_._address(in.address());
1009 if constexpr (!_Physical) {
1010 this->ptr_._page_directory(in.page_directory());
1017 this->ptr_.reset(x64, in.address(), in.length());
1019 this->ptr_.reset(x64, in.address(),
length);
1023 this->ptr_.reset(x64, in.address(),
length);
1027 this->ptr_.reset(x64, in.address());
1031 template <
typename InTp,
typename InPtrType>
1032 void _copy_guest_ptr_t(
const basic_guest_ptr<InTp, InPtrType, _Physical>& in) {
1033 if constexpr (std::is_pointer_v<std::remove_extent_t<InTp>> && is_guest_size_v<InPtrType>) {
1035 this->ptr_.reset(in.ptr_);
1038 static constexpr bool x64 = std::is_same_v<InPtrType, uint64_t>;
1039 this->ptr_.reset(x64);
1040 this->ptr_._mapping(in._mapping());
1041 _copy_from_guest_ptr_t_base(in);
1044 template <
typename InTp,
typename InPtrType>
1045 void _copy_guest_ptr_t(
const basic_guest_ptr<InTp, InPtrType, _Physical>& in,
size_t length) {
1046 if constexpr (std::is_pointer_v<std::remove_extent_t<InTp>> && is_guest_size_v<InPtrType>) {
1047 this->ptr_.reset(in.ptr_,
length);
1050 static constexpr bool x64 = std::is_same_v<InPtrType, uint64_t>;
1051 this->ptr_.reset(x64);
1052 this->ptr_._mapping(in._mapping());
1053 _copy_from_guest_ptr_t_base(in,
length);
1056 template <
typename InTp,
typename InPtrType>
1057 void _move_guest_ptr_t(basic_guest_ptr<InTp, InPtrType, _Physical>&& in) {
1058 if constexpr (std::is_pointer_v<std::remove_extent_t<InTp>> && is_guest_size_v<InPtrType>) {
1059 this->ptr_.reset(std::move(in.ptr_));
1062 static constexpr bool x64 = std::is_same_v<InPtrType, uint64_t>;
1063 this->ptr_.reset(x64);
1064 this->ptr_._mapping(std::move(in._mapping()));
1065 _copy_from_guest_ptr_t_base(in);
1068 template <
typename InTp,
typename InPtrType>
1069 void _move_guest_ptr_t(basic_guest_ptr<InTp, InPtrType, _Physical>&& in,
size_t length) {
1070 if constexpr (std::is_pointer_v<std::remove_extent_t<InTp>> && is_guest_size_v<InPtrType>) {
1071 this->ptr_.reset(this->ptr_.x64(), std::move(in.ptr_),
length);
1074 static constexpr bool x64 = std::is_same_v<InPtrType, uint64_t>;
1075 this->ptr_.reset(x64);
1076 this->ptr_._mapping(std::move(in._mapping()));
1077 _copy_from_guest_ptr_t_base(in,
length);
1082 template <
typename InTp,
typename InPtrType,
bool InPhysical>
1083 void _copy(
const basic_guest_ptr<InTp, InPtrType, InPhysical>& in) {
1085 static_assert(!(
_is_array_v && !std::is_array_v<InTp>),
1086 "A length is required to convert from non-array to array");
1089 _copy_guest_ptr_t(in);
1092 this->_copy_base(in);
1096 template <
typename InTp,
typename InPtrType,
bool InPhysical>
1097 void _copy(
const basic_guest_ptr<InTp, InPtrType, InPhysical>& in,
size_t length) {
1099 static_assert(
_is_array_v,
"_copy() with length only valid for arrays");
1101 _copy_guest_ptr_t(in,
length);
1105 this->_copy_base(in,
length);
1110 template <
typename InTp,
typename InPtrType,
bool InPhysical>
1111 void _move(basic_guest_ptr<InTp, InPtrType, InPhysical>&& in) {
1113 static_assert(!(
_is_array_v && !std::is_array_v<InTp>),
1114 "A length is required to convert from non-array to array");
1116 _move_guest_ptr_t(std::move(in));
1118 this->
mapping_ = std::move(in._mapping());
1119 this->_copy_base(in);
1124 template <
typename InTp,
typename InPtrType,
bool InPhysical>
1125 void _move(basic_guest_ptr<InTp, InPtrType, InPhysical>&& in,
size_t length) {
1127 static_assert(
_is_array_v,
"_copy() with length only valid for arrays");
1129 _move_guest_ptr_t(std::move(in),
length);
1131 this->
mapping_ = std::move(in._mapping());
1132 this->_copy_base(in,
length);
1138 inline const auto& _mapping()
const {
1140 return this->ptr_._mapping();
1145 inline auto& _mapping() {
1147 return this->ptr_._mapping();
1152 inline void _mapping(
const std::shared_ptr<GuestMemoryMapping>& in) {
1154 this->ptr_._mapping(in);
1159 inline void _mapping(std::shared_ptr<GuestMemoryMapping>&& in) {
1161 this->ptr_._mapping(std::move(in));
1166 inline auto _buffer()
const {
1168 return this->ptr_._buffer();
1175 this->ptr_._buffer(in);
1180 inline void _domain(
const Domain* in) {
1182 this->ptr_._domain(in);
1187 inline void _address(uint64_t in) {
1189 this->ptr_._address(in);
1194 inline void _page_directory(uint64_t in) {
1196 this->ptr_._page_directory(in);
1201 inline void _length(
size_t in) {
1203 this->ptr_._length(in);
1210 template <
typename U,
typename PtrType,
bool Physical,
typename Enabled>
1214 template <
typename OutTp,
typename OutPtrType,
typename InTp,
typename InPtrType,
bool Physical>
1217 template <
typename OutTp,
typename OutPtrType,
typename InTp,
typename InPtrType,
bool Physical>
1220 template <
typename OutTp,
typename OutPtrType,
typename InTp,
typename InPtrType,
bool Physical>
1223 template <
typename OutTp,
typename OutPtrType,
typename InTp,
typename InPtrType,
bool Physical>
1226 template <
typename OutTp,
typename OutPtrType,
typename InTp,
typename InPtrType,
bool Physical>
1229 template <
typename OutTp,
typename OutPtrType,
typename InTp,
typename InPtrType,
bool Physical>
1232 template <
typename OutTp,
typename OutPtrType,
typename InTp,
typename InPtrType,
bool Physical>
1237template <
typename _OutTp,
typename _OutPtrType = void,
typename _InTp,
typename _PtrType,
1242 out._domain(&(in.
domain()));
1243 if constexpr (!_Physical) {
1246 if constexpr (std::is_array_v<_OutTp>) {
1248 static_assert(std::is_array_v<_InTp>,
"Cannot cast from non-array to array directly");
1256template <
typename _OutTp,
typename _OutPtrType = void,
typename _InTp,
typename _PtrType,
1258basic_guest_ptr<_OutTp, _OutPtrType, _Physical>
1263 result._mapping(in._mapping());
1264 result._buffer(
const_cast<_OutTp*
>(in._buffer()));
1265 _ptr_cast_impl<_OutTp>(in, result);
1268template <
typename _OutTp,
typename _OutPtrType = void,
typename _InTp,
typename _PtrType,
1270basic_guest_ptr<_OutTp, _OutPtrType, _Physical>
1275 result._mapping(in._mapping());
1276 result._buffer(
static_cast<_OutTp*
>(in._buffer()));
1277 _ptr_cast_impl<_OutTp>(in, result);
1280template <
typename _OutTp,
typename _OutPtrType = void,
typename _InTp,
typename _PtrType,
1282basic_guest_ptr<_OutTp, _OutPtrType, _Physical>
1287 result._mapping(in._mapping());
1288 result._buffer(
reinterpret_cast<_OutTp*
>(in._buffer()));
1289 _ptr_cast_impl<_OutTp>(in, result);
1294template <
typename _OutTp,
typename _OutPtrType = void,
typename _InTp,
typename _PtrType,
1296basic_guest_ptr<_OutTp, _OutPtrType, _Physical>
1301 result._mapping(std::move(in._mapping()));
1302 result._buffer(
const_cast<_OutTp*
>(in._buffer()));
1303 _ptr_cast_impl<_OutTp>(in, result);
1306template <
typename _OutTp,
typename _OutPtrType = void,
typename _InTp,
typename _PtrType,
1308basic_guest_ptr<_OutTp, _OutPtrType, _Physical>
1313 result._mapping(std::move(in._mapping()));
1314 result._buffer(
static_cast<_OutTp*
>(in._buffer()));
1315 _ptr_cast_impl<_OutTp>(in, result);
1318template <
typename _OutTp,
typename _OutPtrType = void,
typename _InTp,
typename _PtrType,
1320basic_guest_ptr<_OutTp, _OutPtrType, _Physical>
1325 result._mapping(std::move(in._mapping()));
1326 result._buffer(
reinterpret_cast<_OutTp*
>(in._buffer()));
1327 _ptr_cast_impl<_OutTp>(in, result);
1333template <
typename _CharType,
typename _OutPtrType = void,
typename _Tp,
typename _PtrType,
1336 size_t max_length = 0xFFFF) {
1339 std::conditional_t<std::is_const_v<_Tp>, std::add_const_t<_CharType>, _CharType>;
1342 constexpr std::size_t char_size =
sizeof(std::remove_all_extents_t<_CharType>);
1348 std::size_t bytes_available = PageDirectory::PAGE_SIZE - ptr.
page_offset();
1349 std::size_t chars_available = bytes_available / char_size;
1351 if constexpr (char_size > 1) {
1352 if (
unlikely(chars_available == 0)) {
1355 bytes_available += PageDirectory::PAGE_SIZE;
1356 chars_available = bytes_available / char_size;
1363 if constexpr (std::is_void_v<_Tp>) {
1364 result.
reset(ptr, chars_available);
1365 }
else if constexpr (!std::is_void_v<_Tp>) {
1371 while (offset < chars_available) {
1372 if (result[offset] == 0)
1376 if (
unlikely(++offset >= max_length)) {
1382 bytes_available += PageDirectory::PAGE_SIZE;
1383 chars_available = bytes_available / char_size;
1402template <
typename _Tp,
typename _PtrType,
bool _Physical>
1403inline basic_guest_ptr<char[], void, _Physical>
1405 size_t max_length = 0xFFFF) {
1406 return _map_guest_str<char[]>(ptr);
1415template <
typename _Tp,
typename _PtrType,
bool _Physical>
1416inline basic_guest_ptr<char16_t[], void, _Physical>
1418 size_t max_length = 0xFFFF) {
1419 return _map_guest_str<char16_t[]>(ptr);
1425template <
typename _Tp,
typename _PtrType,
bool _Physical>
1431template <
typename _Tp,
typename _PtrType,
bool _Physical>
A class representing a single Domain.
Definition Domain.hh:44
virtual std::shared_ptr< GuestMemoryMapping > map_pfns(const uint64_t *pfns, size_t count) const =0
Map a list of pfns into our address space.
virtual const x86::PageDirectory & page_directory() const =0
Get the page directory for address translation.
A class representing a single virtual processor.
Definition Vcpu.hh:33
virtual Registers & registers()=0
Get the processor's registers.
virtual Domain & domain()=0
Get the domain associated with this Vcpu.
basic_guest_ptr< guest_ptr_t, void, _Physical > ptr_
Definition guest_ptr.hh:73
basic_guest_ptr< guest_ptr_t[], void, _Physical > ptr_
Definition guest_ptr.hh:78
size_t length_
Definition guest_ptr.hh:56
Definition guest_ptr.hh:50
Definition guest_ptr.hh:39
uint64_t page_directory_
Definition guest_ptr.hh:41
Definition guest_ptr.hh:61
_Tp * buffer_
Definition guest_ptr.hh:66
const Domain * domain_
Definition guest_ptr.hh:63
uint64_t address_
Definition guest_ptr.hh:64
std::shared_ptr< GuestMemoryMapping > mapping_
Definition guest_ptr.hh:65
Definition guest_ptr.hh:88
void _reset(uint64_t address, size_t length=0)
Definition guest_ptr.hh:811
friend basic_guest_ptr< OutTp, OutPtrType, Physical > const_ptr_cast(const basic_guest_ptr< InTp, InPtrType, Physical > &)
void reset(const Domain &domain, uint64_t address, size_t length)
Definition guest_ptr.hh:416
friend basic_guest_ptr< OutTp, OutPtrType, Physical > reinterpret_ptr_cast(const basic_guest_ptr< InTp, InPtrType, Physical > &)
bool operator>(const basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > &in) const
Definition guest_ptr.hh:679
basic_guest_ptr< basic_type, std::conditional_t< _is_ppointer_v, _PtrType, void >, _Physical > outptr_type
Definition guest_ptr.hh:107
bool operator<(const basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > &in) const
Definition guest_ptr.hh:673
basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > & operator+=(I offset)
Definition guest_ptr.hh:599
static constexpr bool _is_void_v
Definition guest_ptr.hh:100
friend void _ptr_cast_impl(const basic_guest_ptr< InTp, InPtrType, Physical > &, basic_guest_ptr< OutTp, OutPtrType, Physical > &)
Friend the casting functions.
static constexpr bool _is_array_v
Definition guest_ptr.hh:96
bool operator!=(const basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > &in) const
Definition guest_ptr.hh:693
basic_guest_ptr()
Default constructor and null reset.
Definition guest_ptr.hh:343
basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > & operator-=(I offset)
Definition guest_ptr.hh:630
basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > operator+(I offset) const
Definition guest_ptr.hh:614
uint64_t page_mask() const
Definition guest_ptr.hh:131
void set(const basic_guest_ptr< InTp, InPtrType, _Physical > &in) const
Definition guest_ptr.hh:295
void reset(const Domain &domain, uint64_t address, uint64_t page_directory, size_t length)
Definition guest_ptr.hh:454
void set(size_t index, const basic_guest_ptr< InTp, InPtrType, _Physical > &in) const
Definition guest_ptr.hh:309
basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > operator--(int)
Definition guest_ptr.hh:623
std::string_view str() const
Definition guest_ptr.hh:705
std::string str() const
Definition guest_ptr.hh:725
friend basic_guest_ptr< OutTp, OutPtrType, Physical > static_ptr_cast(const basic_guest_ptr< InTp, InPtrType, Physical > &)
basic_guest_ptr(bool x64, Arguments &&... args)
Special constructor and reset for guest_ptr_t variant.
Definition guest_ptr.hh:381
uint64_t page_offset() const
Definition guest_ptr.hh:133
typename std::add_pointer_t< basic_type > pointer_type
Definition guest_ptr.hh:93
basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > & operator=(const basic_guest_ptr< Tp, PtrType, _Physical > &in)
Definition guest_ptr.hh:528
void reset(const Domain &domain, uint64_t address)
Definition guest_ptr.hh:400
decltype(auto) at(size_t index) const
Definition guest_ptr.hh:256
friend basic_guest_ptr< OutTp, OutPtrType, Physical > const_ptr_cast(basic_guest_ptr< InTp, InPtrType, Physical > &&)
size_t length() const
Definition guest_ptr.hh:153
auto get() const
Definition guest_ptr.hh:246
auto operator->() const
Definition guest_ptr.hh:181
basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > & operator=(basic_guest_ptr< Tp, PtrType, _Physical > &&in)
Definition guest_ptr.hh:556
friend basic_guest_ptr< OutTp, OutPtrType, Physical > reinterpret_ptr_cast(basic_guest_ptr< InTp, InPtrType, Physical > &&)
basic_guest_ptr(const Domain &domain, uint64_t address, uint64_t page_directory, size_t length)
Definition guest_ptr.hh:446
typename std::add_lvalue_reference_t< basic_type > ref_type
Definition guest_ptr.hh:94
typename std::remove_pointer_t< std::remove_extent_t< _Tp > > basic_type
Definition guest_ptr.hh:91
static constexpr bool _is_ppointer_v
Definition guest_ptr.hh:98
void reset(basic_guest_ptr< Tp, PtrType, _Physical > &&in, size_t length)
Definition guest_ptr.hh:565
void set(size_t index, type value) const
Definition guest_ptr.hh:285
std::remove_extent_t< _Tp > array_element_type
Definition guest_ptr.hh:92
basic_guest_ptr(const Vcpu &vcpu, uint64_t address)
Helper constructor and reset using a vcpu.
Definition guest_ptr.hh:465
basic_guest_ptr(const Domain &domain, uint64_t address)
Physical pointer constructors.
Definition guest_ptr.hh:394
static constexpr bool _is_pointer_v
Definition guest_ptr.hh:97
void reset(basic_guest_ptr< Tp, PtrType, _Physical > &&in)
Definition guest_ptr.hh:561
static constexpr bool _is_void_ptr
Definition guest_ptr.hh:101
void set(type value) const
Setter methods.
Definition guest_ptr.hh:275
static constexpr bool _is_guest_ptr_t_v
Definition guest_ptr.hh:103
static constexpr bool _is_access_allowed
Definition guest_ptr.hh:104
void _remap()
Definition guest_ptr.hh:765
pointer_type begin() const
Array operations for non-pointer types.
Definition guest_ptr.hh:332
void reset(const Vcpu &vcpu, uint64_t address)
Definition guest_ptr.hh:466
uint64_t page_number() const
Definition guest_ptr.hh:132
uint64_t page_directory() const
Definition guest_ptr.hh:134
uint64_t address() const
Functions for getting the underlying address.
Definition guest_ptr.hh:124
basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > operator-(I offset) const
Definition guest_ptr.hh:645
bool operator<=(const basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > &in) const
Definition guest_ptr.hh:676
bool operator>=(const basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > &in) const
Definition guest_ptr.hh:682
static constexpr bool _is_non_guest_ptr_t_v
Definition guest_ptr.hh:102
basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > operator++(int)
Definition guest_ptr.hh:592
const Domain & domain() const
Definition guest_ptr.hh:144
ptrdiff_t operator-(const basic_guest_ptr< Tp, PtrType, _Physical > &in) const
Definition guest_ptr.hh:654
void reset(const Vcpu &vcpu, uint64_t address, size_t length)
Definition guest_ptr.hh:478
void _validate_valid_ptr() const
Definition guest_ptr.hh:871
void reset(bool x64, Arguments &&... args)
Definition guest_ptr.hh:386
basic_guest_ptr(const Domain &domain, uint64_t address, size_t length)
Definition guest_ptr.hh:410
basic_guest_ptr(std::nullptr_t)
Special constructor to automatically create from nullptr.
Definition guest_ptr.hh:363
void reset(const Domain &domain, uint64_t address, uint64_t page_directory)
Definition guest_ptr.hh:435
basic_guest_ptr(const Domain &domain, uint64_t address, uint64_t page_directory)
Virtual pointer constructors and reset methods.
Definition guest_ptr.hh:428
void reset(const basic_guest_ptr< Tp, PtrType, _Physical > &in)
Definition guest_ptr.hh:533
void reset()
Definition guest_ptr.hh:345
bool operator==(const basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > &in) const
Definition guest_ptr.hh:685
std::u16string_view wstr() const
Definition guest_ptr.hh:719
pointer_type end() const
Definition guest_ptr.hh:337
friend basic_guest_ptr< OutTp, OutPtrType, Physical > static_ptr_cast(basic_guest_ptr< InTp, InPtrType, Physical > &&)
void reset(uint64_t address)
Helper reset methods specifying only an address (and length for arrays)
Definition guest_ptr.hh:489
std::ostream & write_stream(std::ostream &os) const
Definition guest_ptr.hh:734
basic_guest_ptr< void, void, _Physical, void > clone(uint64_t address) const
Helper to create a new instance of this pointer.
Definition guest_ptr.hh:570
basic_guest_ptr(const basic_guest_ptr< _Tp, InPtrType, false > &in)
Special constructor to create guest_phys_ptr from guest_ptr.
Definition guest_ptr.hh:368
basic_guest_ptr< _Tp, _PtrType, _Physical, _Enabled > & operator--()
Definition guest_ptr.hh:621
basic_guest_ptr(const Vcpu &vcpu, uint64_t address, size_t length)
Definition guest_ptr.hh:475
void _reconfigure_buffer()
Definition guest_ptr.hh:749
static std::string convert(std::u16string_view src)
Convert a UTF16 string to UTF8.
virtual uint64_t cr3() const =0
Get control register 3.
#define unlikely(x)
Definition compiler.hh:27
#define introvirt_assert(condition, msg)
Definition introvirt_assert.hh:32
Core IntroVirt classes.
Definition Cr0.hh:20
const std::string & to_string(OS)
basic_guest_ptr< _OutTp, _OutPtrType, _Physical > const_ptr_cast(const basic_guest_ptr< _InTp, _PtrType, _Physical > &in)
Copy casting functions.
Definition guest_ptr.hh:1259
std::string n2hexstr(I w, size_t hex_len=sizeof(I)<< 1)
Definition n2hexstr.hh:23
basic_guest_ptr< char16_t[], void, _Physical > map_guest_wstring(const basic_guest_ptr< _Tp, _PtrType, _Physical > &ptr, size_t max_length=0xFFFF)
Helper function for map_guest_str<char16_t>
Definition guest_ptr.hh:1417
auto _map_guest_str(const basic_guest_ptr< _Tp, _PtrType, _Physical > &ptr, size_t max_length=0xFFFF)
Null terminated array helpers.
Definition guest_ptr.hh:1335
basic_guest_ptr< _OutTp, _OutPtrType, _Physical > static_ptr_cast(const basic_guest_ptr< _InTp, _PtrType, _Physical > &in)
Definition guest_ptr.hh:1271
void _ptr_cast_impl(const basic_guest_ptr< _InTp, _PtrType, _Physical > &in, basic_guest_ptr< _OutTp, _OutPtrType, _Physical > &out)
Definition guest_ptr.hh:1239
basic_guest_ptr< _OutTp, _OutPtrType, _Physical > reinterpret_ptr_cast(const basic_guest_ptr< _InTp, _PtrType, _Physical > &in)
Definition guest_ptr.hh:1283
std::ostream & operator<<(std::ostream &, OS)
basic_guest_ptr< char[], void, _Physical > map_guest_cstring(const basic_guest_ptr< _Tp, _PtrType, _Physical > &ptr, size_t max_length=0xFFFF)
Helper function for map_guest_str<char>
Definition guest_ptr.hh:1404