Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/Format.h>
10#include <AK/Types.h>
11
12class VirtualAddress {
13public:
14 VirtualAddress() = default;
15 constexpr explicit VirtualAddress(FlatPtr address)
16 : m_address(address)
17 {
18 }
19
20 explicit VirtualAddress(void const* address)
21 : m_address((FlatPtr)address)
22 {
23 }
24
25 [[nodiscard]] constexpr bool is_null() const { return m_address == 0; }
26 [[nodiscard]] constexpr bool is_page_aligned() const { return (m_address & 0xfff) == 0; }
27
28 [[nodiscard]] constexpr VirtualAddress offset(FlatPtr o) const { return VirtualAddress(m_address + o); }
29 [[nodiscard]] constexpr FlatPtr get() const { return m_address; }
30 void set(FlatPtr address) { m_address = address; }
31 void mask(FlatPtr m) { m_address &= m; }
32
33 bool operator<=(VirtualAddress const& other) const { return m_address <= other.m_address; }
34 bool operator>=(VirtualAddress const& other) const { return m_address >= other.m_address; }
35 bool operator>(VirtualAddress const& other) const { return m_address > other.m_address; }
36 bool operator<(VirtualAddress const& other) const { return m_address < other.m_address; }
37 bool operator==(VirtualAddress const& other) const { return m_address == other.m_address; }
38 bool operator!=(VirtualAddress const& other) const { return m_address != other.m_address; }
39
40 // NOLINTNEXTLINE(readability-make-member-function-const) const VirtualAddress shouldn't be allowed to modify the underlying memory
41 [[nodiscard]] u8* as_ptr() { return reinterpret_cast<u8*>(m_address); }
42 [[nodiscard]] u8 const* as_ptr() const { return reinterpret_cast<u8 const*>(m_address); }
43
44 [[nodiscard]] VirtualAddress page_base() const { return VirtualAddress(m_address & ~(FlatPtr)0xfffu); }
45
46private:
47 FlatPtr m_address { 0 };
48};
49
50inline VirtualAddress operator-(VirtualAddress const& a, VirtualAddress const& b)
51{
52 return VirtualAddress(a.get() - b.get());
53}
54
55template<>
56struct AK::Formatter<VirtualAddress> : AK::Formatter<FormatString> {
57 ErrorOr<void> format(FormatBuilder& builder, VirtualAddress const& value)
58 {
59 return AK::Formatter<FormatString>::format(builder, "V{}"sv, value.as_ptr());
60 }
61};