fxos/lib/AbstractMemory.cpp

105 lines
3.0 KiB
C++

//---------------------------------------------------------------------------//
// 1100101 |_ mov #0, r4 __ //
// 11 |_ <0xb380 %5c4> / _|_ _____ ___ //
// 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< //
// |_ base# + offset |_| /_\_\___/__/ //
//---------------------------------------------------------------------------//
#include <fxos/AbstractMemory.h>
#include <cstring>
namespace FxOS {
bool AbstractMemory::covers(uint32_t addr, int size)
{
return (this->translate(addr, size) != nullptr);
}
bool AbstractMemory::covers(MemoryRegion const &region)
{
return this->covers(region.start, region.size());
}
char const *AbstractMemory::translate(uint32_t addr, int size)
{
int actual_size;
char const *ptr = this->translate_dynamic(addr, &actual_size);
return (ptr && actual_size >= size) ? ptr : nullptr;
}
Addressable<int8_t> AbstractMemory::read_i8(uint32_t addr)
{
int8_t *i8 = (int8_t *)this->translate(addr, 1);
if(!i8)
return Addressable((int8_t)-1);
return Addressable(addr, *i8);
}
Addressable<uint8_t> AbstractMemory::read_u8(uint32_t addr)
{
uint8_t *u8 = (uint8_t *)this->translate(addr, 1);
if(!u8)
return Addressable((uint8_t)-1);
return Addressable(addr, *u8);
}
Addressable<int16_t> AbstractMemory::read_i16(uint32_t addr)
{
uint8_t *i16 = (uint8_t *)this->translate(addr, 2);
if(!i16)
return Addressable((int16_t)-1);
int16_t v = (i16[0] << 8) | i16[1];
return Addressable(addr, v);
}
Addressable<uint16_t> AbstractMemory::read_u16(uint32_t addr)
{
uint8_t *u16 = (uint8_t *)this->translate(addr, 2);
if(!u16)
return Addressable((uint16_t)-1);
uint16_t v = (u16[0] << 8) | u16[1];
return Addressable(addr, v);
}
Addressable<int32_t> AbstractMemory::read_i32(uint32_t addr)
{
uint8_t *i32 = (uint8_t *)this->translate(addr, 4);
if(!i32)
return Addressable((int32_t)-1);
int32_t v = (i32[0] << 24) | (i32[1] << 16) | (i32[2] << 8) | i32[3];
return Addressable(addr, v);
}
Addressable<uint32_t> AbstractMemory::read_u32(uint32_t addr)
{
uint8_t *u32 = (uint8_t *)this->translate(addr, 4);
if(!u32)
return Addressable((uint32_t)-1);
uint32_t v = (u32[0] << 24) | (u32[1] << 16) | (u32[2] << 8) | u32[3];
return Addressable(addr, v);
}
Addressable<std::string> AbstractMemory::read_str(uint32_t addr, size_t len)
{
char const *str = this->translate(addr, len);
if(!str)
return Addressable(std::string());
return Addressable(addr, std::string(str, len));
}
uint32_t AbstractMemory::search(
uint32_t start, uint32_t end, void const *pattern, int size)
{
void const *data = translate(start, end - start);
if(!data)
return end;
void const *occurrence = memmem(data, end - start, pattern, size);
if(!occurrence)
return end;
return start + ((char *)occurrence - (char *)data);
}
} /* namespace FxOS */