~satchmo/libvmm

ref: d1e2394c16ab1264d23a2c78607433815c3fbb23 libvmm/vmm/memory/detail/guest.hpp -rw-r--r-- 4.5 KiB
d1e2394cJason Phan memory: Move includes in addres.hpp out of namespace 8 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//
// guest.hpp -
//

#pragma once

#include <cassert> // assert
#include <cstdint> // uint*_t
#include <filesystem> // path
#include <fstream> // fstream
#include <ios> // ios_base
#include <iostream> // ostream
#include <memory> // shared_ptr
#include <stdexcept> // runtime_error
#include <string> // string

#include "vmm/memory/detail/address.hpp" // Address, AddressValue

namespace vmm::memory::detail {

// A guest physical address.
//
// On aarch64, a 32-bit hypervisor may be used to support a 64-bit guest. For
// simplicity, uint64_t is used to store the raw value regardless of whether
// the guest is 32-bit or 64-bit.
class GuestAddress : public Address<GuestAddress, uint64_t>
{
    public:
        using value_type = GuestAddress;
        using size_type = uint64_t;
        using reference = value_type&;
        using const_reference = const value_type&;

        explicit GuestAddress(size_type addr=0) noexcept : m_addr{addr} {}

        auto data() const noexcept -> size_type override;

        auto operator&(const size_type mask) const noexcept -> size_type override;
        auto operator|(const size_type mask) const noexcept -> size_type override;
        auto operator+(const size_type val) const noexcept -> value_type override;
        auto operator+(const_reference addr) const noexcept -> value_type override;
        auto operator-(const size_type val) const noexcept -> value_type override;
        auto operator-(const_reference addr) const noexcept -> value_type override;

        auto align(const size_type alignment) noexcept -> reference override;
    private:
        size_type m_addr{};
};

// An offset into a memory region.
class MemoryRegionAddress : public Address<MemoryRegionAddress, uint64_t>
{
    public:
        using value_type = MemoryRegionAddress;
        using size_type = uint64_t;
        using reference = value_type&;
        using const_reference = const value_type&;

        explicit MemoryRegionAddress(size_type addr=0) noexcept : m_addr{addr} {}

        auto data() const noexcept -> size_type override;

        auto operator&(const size_type mask) const noexcept -> size_type override;
        auto operator|(const size_type mask) const noexcept -> size_type override;
        auto operator+(const size_type val) const noexcept -> value_type override;
        auto operator+(const_reference addr) const noexcept -> value_type override;
        auto operator-(const size_type val) const noexcept -> value_type override;
        auto operator-(const_reference addr) const noexcept -> value_type override;

        auto align(const size_type alignment) noexcept -> reference override;
    private:
        size_type m_addr{};
};

// The starting point of a file which backs a GuestMemoryRegion.
class FileOffset
{
    private:
        std::shared_ptr<std::fstream> m_fstream;
        long m_start{};
    public:
        FileOffset(const char* filename, std::ios_base::openmode mode,
                   const long start={})
            : m_fstream{std::make_shared<std::fstream>(filename, mode)},
              m_start{start}
        {
            if (start) {
                // TODO (?): Only call these if the appropriate openmode is set.
                m_fstream->seekg(start);
                m_fstream->seekp(start);
            }
        }

        explicit FileOffset(const char* filename, const long start={})
            : FileOffset(filename, std::ios_base::in | std::ios_base::out, start) {}

        explicit FileOffset(const std::string& filename, const long start=0)
            : FileOffset(filename.c_str(), start) {}

        FileOffset(const std::string& filename,
                   const std::ios_base::openmode mode,
                   const long start={})
            : FileOffset(filename.c_str(), mode, start) {}

        explicit FileOffset(const std::filesystem::path& filename, const long start=0)
            : FileOffset(filename.c_str(), start) {}

        FileOffset(const std::filesystem::path& filename,
                   const std::ios_base::openmode mode,
                   const long start={})
            : FileOffset(filename.c_str(), mode, start) {}

        // TODO: thread-safety
        [[nodiscard]] auto data() const -> std::basic_filebuf<std::fstream::char_type,
                                                              std::fstream::traits_type>*
        {
            return m_fstream->rdbuf();
        }

        [[nodiscard]] constexpr auto start() const noexcept -> long
        {
            return m_start;
        }
};

}  // vmm::memory::detail