diff options
author | Brian Geffon <bgeffon@google.com> | 2018-12-10 14:41:40 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-12-10 14:42:34 -0800 |
commit | d3bc79bc8438206ac6a14fde4eaa288fc07eee82 (patch) | |
tree | e820398591bfd1503456e877fa0c2bdd0f994959 /test/util/memory_util.h | |
parent | 833edbd10b49db1f934dcb2495dcb41c1310eea4 (diff) |
Open source system call tests.
PiperOrigin-RevId: 224886231
Change-Id: I0fccb4d994601739d8b16b1d4e6b31f40297fb22
Diffstat (limited to 'test/util/memory_util.h')
-rw-r--r-- | test/util/memory_util.h | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/test/util/memory_util.h b/test/util/memory_util.h new file mode 100644 index 000000000..8f6e99ba6 --- /dev/null +++ b/test/util/memory_util.h @@ -0,0 +1,124 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GVISOR_TEST_UTIL_MEMORY_UTIL_H_ +#define GVISOR_TEST_UTIL_MEMORY_UTIL_H_ + +#include <errno.h> +#include <stddef.h> +#include <stdint.h> +#include <sys/mman.h> + +#include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" +#include "test/util/logging.h" +#include "test/util/posix_error.h" +#include "test/util/save_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +// RAII type for mmap'ed memory. Only usable in tests due to use of a test-only +// macro that can't be named without invoking the presubmit's wrath. +class Mapping { + public: + // Constructs a mapping that owns nothing. + Mapping() = default; + + // Constructs a mapping that owns the mmapped memory [ptr, ptr+len). Most + // users should use Mmap or MmapAnon instead. + Mapping(void* ptr, size_t len) : ptr_(ptr), len_(len) {} + + Mapping(Mapping&& orig) : ptr_(orig.ptr_), len_(orig.len_) { orig.release(); } + + Mapping& operator=(Mapping&& orig) { + ptr_ = orig.ptr_; + len_ = orig.len_; + orig.release(); + return *this; + } + + Mapping(Mapping const&) = delete; + Mapping& operator=(Mapping const&) = delete; + + ~Mapping() { reset(); } + + void* ptr() const { return ptr_; } + size_t len() const { return len_; } + + // Returns a pointer to the end of the mapping. Useful for when the mapping + // is used as a thread stack. + void* endptr() const { return reinterpret_cast<void*>(addr() + len_); } + + // Returns the start of this mapping cast to uintptr_t for ease of pointer + // arithmetic. + uintptr_t addr() const { return reinterpret_cast<uintptr_t>(ptr_); } + + // Returns the end of this mapping cast to uintptr_t for ease of pointer + // arithmetic. + uintptr_t endaddr() const { return reinterpret_cast<uintptr_t>(endptr()); } + + // Returns this mapping as a StringPiece for ease of comparison. + // + // This function is named view in anticipation of the eventual replacement of + // StringPiece with std::string_view. + absl::string_view view() const { + return absl::string_view(static_cast<char const*>(ptr_), len_); + } + + // These are both named reset for consistency with standard smart pointers. + + void reset(void* ptr, size_t len) { + if (len_) { + TEST_PCHECK(munmap(ptr_, len_) == 0); + } + ptr_ = ptr; + len_ = len; + } + + void reset() { reset(nullptr, 0); } + + void release() { + ptr_ = nullptr; + len_ = 0; + } + + private: + void* ptr_ = nullptr; + size_t len_ = 0; +}; + +// Wrapper around mmap(2) that returns a Mapping. +inline PosixErrorOr<Mapping> Mmap(void* addr, size_t length, int prot, + int flags, int fd, off_t offset) { + void* ptr = mmap(addr, length, prot, flags, fd, offset); + if (ptr == MAP_FAILED) { + return PosixError( + errno, absl::StrFormat("mmap(%p, %d, %x, %x, %d, %d)", addr, length, + prot, flags, fd, offset)); + } + MaybeSave(); + return Mapping(ptr, length); +} + +// Convenience wrapper around Mmap for anonymous mappings. +inline PosixErrorOr<Mapping> MmapAnon(size_t length, int prot, int flags) { + return Mmap(nullptr, length, prot, flags | MAP_ANONYMOUS, -1, 0); +} + +} // namespace testing +} // namespace gvisor + +#endif // GVISOR_TEST_UTIL_MEMORY_UTIL_H_ |