2021-04-04 21:04:12 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
2021-09-11 18:52:39 +01:00
|
|
|
#include <cstdint>
|
2024-07-23 21:14:22 +01:00
|
|
|
#include <algorithm>
|
2021-04-04 21:04:12 +01:00
|
|
|
#include <vector>
|
2024-11-16 20:05:26 +00:00
|
|
|
#include <span>
|
2023-08-24 17:25:28 +01:00
|
|
|
#include <set>
|
2022-05-14 22:39:37 +01:00
|
|
|
#include <optional>
|
2024-07-23 21:14:22 +01:00
|
|
|
#include <cassert>
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2023-08-13 15:47:51 +01:00
|
|
|
namespace Targets
|
2021-04-04 21:04:12 +01:00
|
|
|
{
|
2022-09-06 17:16:49 +01:00
|
|
|
using TargetMemoryAddress = std::uint32_t;
|
|
|
|
|
using TargetMemorySize = std::uint32_t;
|
|
|
|
|
using TargetStackPointer = TargetMemoryAddress;
|
|
|
|
|
using TargetMemoryBuffer = std::vector<unsigned char>;
|
2024-11-16 20:05:26 +00:00
|
|
|
using TargetMemoryBufferSpan = std::span<const TargetMemoryBuffer::value_type>;
|
2022-09-06 17:16:49 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
using TargetAddressSpaceId = std::size_t;
|
|
|
|
|
using TargetMemorySegmentId = std::size_t;
|
|
|
|
|
|
2022-02-02 21:52:31 +00:00
|
|
|
enum class TargetMemoryEndianness: std::uint8_t
|
|
|
|
|
{
|
|
|
|
|
BIG,
|
|
|
|
|
LITTLE,
|
|
|
|
|
};
|
|
|
|
|
|
2021-09-11 20:39:31 +01:00
|
|
|
struct TargetMemoryAddressRange
|
|
|
|
|
{
|
2022-09-06 17:16:49 +01:00
|
|
|
TargetMemoryAddress startAddress = 0;
|
|
|
|
|
TargetMemoryAddress endAddress = 0;
|
2021-10-09 19:17:39 +01:00
|
|
|
|
|
|
|
|
TargetMemoryAddressRange() = default;
|
2022-09-06 17:16:49 +01:00
|
|
|
TargetMemoryAddressRange(TargetMemoryAddress startAddress, TargetMemoryAddress endAddress)
|
2022-05-14 22:39:37 +01:00
|
|
|
: startAddress(startAddress)
|
|
|
|
|
, endAddress(endAddress)
|
2024-07-23 21:14:22 +01:00
|
|
|
{
|
|
|
|
|
assert(this->startAddress <= this->endAddress);
|
|
|
|
|
}
|
2021-12-22 03:33:54 +00:00
|
|
|
|
2021-12-25 01:45:33 +00:00
|
|
|
bool operator == (const TargetMemoryAddressRange& rhs) const {
|
|
|
|
|
return this->startAddress == rhs.startAddress && this->endAddress == rhs.endAddress;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-25 20:54:02 +00:00
|
|
|
bool operator < (const TargetMemoryAddressRange& rhs) const {
|
|
|
|
|
return this->startAddress < rhs.startAddress;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
/**
|
|
|
|
|
* Returns the number of addresses in the range.
|
|
|
|
|
*
|
|
|
|
|
* Keep in mind that the number of addresses may not be equal to the number of bytes in the range. It depends
|
|
|
|
|
* on whether the address space is byte-addressable. See TargetAddressSpaceDescriptor::unitSize for more.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] TargetMemorySize size() const {
|
2024-03-16 16:21:39 +00:00
|
|
|
return this->endAddress - this->startAddress + 1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
/**
|
|
|
|
|
* Checks if this range intersects with the given range.
|
|
|
|
|
*
|
|
|
|
|
* @param other
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool intersectsWith(const TargetMemoryAddressRange& other) const noexcept {
|
|
|
|
|
return this->startAddress <= other.endAddress && other.startAddress <= this->endAddress;
|
2021-12-22 03:33:54 +00:00
|
|
|
}
|
2021-12-27 03:55:11 +00:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
/**
|
|
|
|
|
* Returns the number of addresses in this range that intersect with the given range.
|
|
|
|
|
*
|
|
|
|
|
* @param other
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] TargetMemorySize intersectingSize(const TargetMemoryAddressRange& other) const noexcept {
|
|
|
|
|
return this->intersectsWith(other)
|
|
|
|
|
? std::min(this->endAddress, other.endAddress) - std::max(this->startAddress, other.startAddress) + 1
|
|
|
|
|
: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checks if the given address is contained within this range.
|
|
|
|
|
*
|
|
|
|
|
* @param address
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool contains(TargetMemoryAddress address) const noexcept {
|
2021-12-30 13:28:58 +00:00
|
|
|
return address >= this->startAddress && address <= this->endAddress;
|
2021-12-27 03:55:11 +00:00
|
|
|
}
|
2022-01-16 18:50:12 +00:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
/**
|
|
|
|
|
* Checks if the given range is completely contained within this range.
|
|
|
|
|
*
|
|
|
|
|
* @param addressRange
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool contains(const TargetMemoryAddressRange& addressRange) const noexcept {
|
2022-01-16 18:50:12 +00:00
|
|
|
return this->startAddress <= addressRange.startAddress && this->endAddress >= addressRange.endAddress;
|
|
|
|
|
}
|
2023-08-24 17:25:28 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
/**
|
|
|
|
|
* Returns a set of all addresses within this range.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
std::set<Targets::TargetMemoryAddress> addresses() const noexcept {
|
|
|
|
|
auto addresses = std::set<Targets::TargetMemoryAddress>{};
|
2023-08-24 17:25:28 +01:00
|
|
|
auto addressesIt = addresses.end();
|
|
|
|
|
|
|
|
|
|
for (auto i = this->startAddress; i <= this->endAddress; ++i) {
|
|
|
|
|
addressesIt = addresses.insert(addressesIt, i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return addresses;
|
|
|
|
|
}
|
2021-10-09 19:17:39 +01:00
|
|
|
};
|
2021-10-09 19:17:58 +01:00
|
|
|
|
2023-05-03 23:13:22 +01:00
|
|
|
struct TargetMemoryAccess
|
|
|
|
|
{
|
|
|
|
|
bool readable = false;
|
|
|
|
|
bool writeable = false;
|
|
|
|
|
|
|
|
|
|
TargetMemoryAccess(
|
|
|
|
|
bool readable,
|
2024-07-23 21:14:22 +01:00
|
|
|
bool writeable
|
2023-05-03 23:13:22 +01:00
|
|
|
)
|
|
|
|
|
: readable(readable)
|
|
|
|
|
, writeable(writeable)
|
|
|
|
|
{}
|
|
|
|
|
};
|
2021-04-04 21:04:12 +01:00
|
|
|
}
|