Serenity Operating System
1/*
2 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include "SimpleRegion.h"
8#include <AK/ByteReader.h>
9#include <string.h>
10
11namespace UserspaceEmulator {
12
13SimpleRegion::SimpleRegion(u32 base, u32 size)
14 : Region(base, size)
15{
16 m_data = (u8*)calloc(1, size);
17 m_shadow_data = (u8*)malloc(size);
18 memset(m_shadow_data, 1, size);
19}
20
21SimpleRegion::~SimpleRegion()
22{
23 free(m_shadow_data);
24 free(m_data);
25}
26
27ValueWithShadow<u8> SimpleRegion::read8(FlatPtr offset)
28{
29 VERIFY(offset < size());
30 return { m_data[offset], m_shadow_data[offset] };
31}
32
33ValueWithShadow<u16> SimpleRegion::read16(u32 offset)
34{
35 VERIFY(offset + 1 < size());
36
37 u16 value, shadow;
38 ByteReader::load<u16>(m_data + offset, value);
39 ByteReader::load<u16>(m_shadow_data + offset, shadow);
40
41 return { value, shadow };
42}
43
44ValueWithShadow<u32> SimpleRegion::read32(u32 offset)
45{
46 VERIFY(offset + 3 < size());
47
48 u32 value, shadow;
49 ByteReader::load<u32>(m_data + offset, value);
50 ByteReader::load<u32>(m_shadow_data + offset, shadow);
51
52 return { value, shadow };
53}
54
55ValueWithShadow<u64> SimpleRegion::read64(u32 offset)
56{
57 VERIFY(offset + 7 < size());
58
59 u64 value, shadow;
60 ByteReader::load<u64>(m_data + offset, value);
61 ByteReader::load<u64>(m_shadow_data + offset, shadow);
62
63 return { value, shadow };
64}
65
66ValueWithShadow<u128> SimpleRegion::read128(u32 offset)
67{
68 VERIFY(offset + 15 < size());
69 u128 value, shadow;
70 ByteReader::load(m_data + offset, value);
71 ByteReader::load(m_shadow_data + offset, shadow);
72 return { value, shadow };
73}
74
75ValueWithShadow<u256> SimpleRegion::read256(u32 offset)
76{
77 VERIFY(offset + 31 < size());
78 u256 value, shadow;
79 ByteReader::load(m_data + offset, value);
80 ByteReader::load(m_shadow_data + offset, shadow);
81 return { value, shadow };
82}
83
84void SimpleRegion::write8(u32 offset, ValueWithShadow<u8> value)
85{
86 VERIFY(offset < size());
87 m_data[offset] = value.value();
88 m_shadow_data[offset] = value.shadow()[0];
89}
90
91void SimpleRegion::write16(u32 offset, ValueWithShadow<u16> value)
92{
93 VERIFY(offset + 1 < size());
94 ByteReader::store(m_data + offset, value.value());
95 ByteReader::store(m_shadow_data + offset, value.shadow());
96}
97
98void SimpleRegion::write32(u32 offset, ValueWithShadow<u32> value)
99{
100 VERIFY(offset + 3 < size());
101 ByteReader::store(m_data + offset, value.value());
102 ByteReader::store(m_shadow_data + offset, value.shadow());
103}
104
105void SimpleRegion::write64(u32 offset, ValueWithShadow<u64> value)
106{
107 VERIFY(offset + 7 < size());
108 ByteReader::store(m_data + offset, value.value());
109 ByteReader::store(m_shadow_data + offset, value.shadow());
110}
111void SimpleRegion::write128(u32 offset, ValueWithShadow<u128> value)
112{
113 VERIFY(offset + 15 < size());
114 ByteReader::store(m_data + offset, value.value());
115 ByteReader::store(m_shadow_data + offset, value.shadow());
116}
117void SimpleRegion::write256(u32 offset, ValueWithShadow<u256> value)
118{
119 VERIFY(offset + 31 < size());
120 ByteReader::store(m_data + offset, value.value());
121 ByteReader::store(m_shadow_data + offset, value.shadow());
122}
123
124u8* SimpleRegion::cacheable_ptr(u32 offset)
125{
126 return m_data + offset;
127}
128
129}