2024-02-09 23:30:47 +00:00
|
|
|
<?php
|
|
|
|
|
namespace Targets\TargetDescriptionFiles;
|
|
|
|
|
|
2024-12-27 01:53:02 +00:00
|
|
|
require_once __DIR__ . "/AddressRange.php";
|
2024-02-09 23:30:47 +00:00
|
|
|
require_once __DIR__ . "/MemorySegment.php";
|
|
|
|
|
|
|
|
|
|
class AddressSpace
|
|
|
|
|
{
|
|
|
|
|
public ?string $key = null;
|
2024-12-27 01:53:02 +00:00
|
|
|
public ?AddressRange $addressRange = null;
|
2024-07-23 21:14:22 +01:00
|
|
|
public ?int $unitSize = null;
|
2024-02-09 23:30:47 +00:00
|
|
|
public ?string $endianness = null;
|
|
|
|
|
|
|
|
|
|
/** @var MemorySegment[] */
|
|
|
|
|
public array $memorySegments = [];
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
public function __construct(?string $key, ?int $startAddress, ?int $size, ?int $unitSize, ?string $endianness)
|
2024-02-09 23:30:47 +00:00
|
|
|
{
|
|
|
|
|
$this->key = $key;
|
2024-12-27 01:53:02 +00:00
|
|
|
$this->addressRange = is_numeric($startAddress) && is_numeric($size)
|
|
|
|
|
? new AddressRange(
|
|
|
|
|
$startAddress,
|
|
|
|
|
$startAddress + ($size / ($unitSize ?? 1)) - 1
|
|
|
|
|
)
|
|
|
|
|
: null;
|
2024-07-23 21:14:22 +01:00
|
|
|
$this->unitSize = $unitSize;
|
2024-02-09 23:30:47 +00:00
|
|
|
$this->endianness = $endianness;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-27 01:53:02 +00:00
|
|
|
public function size(): ?int
|
|
|
|
|
{
|
|
|
|
|
return $this->addressRange instanceof AddressRange
|
|
|
|
|
? $this->addressRange->size() * ($this->unitSize ?? 1)
|
|
|
|
|
: null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-22 20:54:48 +00:00
|
|
|
public function getMemorySegment(string $key): ?MemorySegment
|
|
|
|
|
{
|
|
|
|
|
foreach ($this->memorySegments as $segment) {
|
|
|
|
|
if ($segment->key === $key) {
|
|
|
|
|
return $segment;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 23:30:47 +00:00
|
|
|
public function totalSegmentSize(): int
|
|
|
|
|
{
|
|
|
|
|
return array_sum(
|
|
|
|
|
array_map(
|
2024-12-27 01:53:02 +00:00
|
|
|
fn (MemorySegment $segment): int => (int) $segment->size(),
|
2024-02-09 23:30:47 +00:00
|
|
|
$this->memorySegments
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-06-05 19:28:49 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns all memory segments that intercept with the given address range.
|
|
|
|
|
*
|
|
|
|
|
* @param int $startAddress
|
|
|
|
|
* @param int $endAddress
|
|
|
|
|
*
|
|
|
|
|
* @return MemorySegment[]
|
|
|
|
|
*/
|
|
|
|
|
public function findIntersectingMemorySegments(int $startAddress, int $endAddress): array
|
|
|
|
|
{
|
|
|
|
|
return array_filter(
|
|
|
|
|
$this->memorySegments,
|
|
|
|
|
function (MemorySegment $segment) use ($startAddress, $endAddress) : bool {
|
2024-12-27 01:53:02 +00:00
|
|
|
$segmentEndAddress = $segment->addressRange->startAddress + $segment->size() - 1;
|
|
|
|
|
return ($startAddress <= $segment->addressRange->startAddress && $endAddress >= $segment->addressRange->startAddress)
|
|
|
|
|
|| ($startAddress >= $segment->addressRange->startAddress && $startAddress <= $segmentEndAddress);
|
2024-06-05 19:28:49 +01:00
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-02-09 23:30:47 +00:00
|
|
|
}
|