mirror of
https://github.com/RKX1209/nsemu.git
synced 2024-05-12 01:25:24 -04:00
Change RAMBlock logic
This commit is contained in:
parent
1e5f0c3acf
commit
f822b1d4a1
|
@ -15,26 +15,25 @@ uint64_t GvaToHva(const uint64_t gva) {
|
|||
template<typename T>
|
||||
static T ReadFromRAM(const uint64_t gpa) {
|
||||
T value = 0;
|
||||
//ns_print("ReadFromRAM: 0x%lx, (%d)\n", gpa, sizeof(T));
|
||||
uint8_t *emu_mem = static_cast<uint8_t *>(Memory::GetRawPtr(gpa, sizeof(T)));
|
||||
debug_print("ReadFromRAM: 0x%lx, (%d)\n", gpa, sizeof(T));
|
||||
for (uint64_t addr = gpa; addr < gpa + sizeof(T); addr++) {
|
||||
uint8_t byte;
|
||||
std::memcpy (&byte, &Memory::pRAM[addr], sizeof(uint8_t));
|
||||
std::memcpy (&byte, &emu_mem[addr - gpa], sizeof(uint8_t));
|
||||
value = value | ((uint64_t)byte << (8 * (addr - gpa)));
|
||||
}
|
||||
uint8_t *ptr = &Memory::pRAM[gpa];
|
||||
bindump (ptr, sizeof(T));
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void WriteToRAM(const uint64_t gpa, T value) {
|
||||
uint8_t *emu_mem = static_cast<uint8_t *>(Memory::GetRawPtr(gpa, sizeof(T)));
|
||||
debug_print("WriteToRAM: 0x%lx, (%d)\n", gpa, sizeof(T));
|
||||
for (uint64_t addr = gpa; addr < gpa + sizeof(T); addr++) {
|
||||
uint8_t byte = value & 0xff;
|
||||
std::memcpy (&Memory::pRAM[addr], &byte, sizeof(uint8_t));
|
||||
std::memcpy (&emu_mem[addr - gpa], &byte, sizeof(uint8_t));
|
||||
value >>= 8;
|
||||
}
|
||||
uint8_t *ptr = &Memory::pRAM[gpa];
|
||||
bindump (ptr, sizeof(T));
|
||||
}
|
||||
|
||||
void ReadBytes(uint64_t gva, uint8_t *ptr, int size) {
|
||||
|
|
2
Cpu.cpp
2
Cpu.cpp
|
@ -29,7 +29,7 @@ State GetState() {
|
|||
}
|
||||
|
||||
void DumpMachine() {
|
||||
//ARMv8::Dump ();
|
||||
ARMv8::Dump ();
|
||||
if (TraceOut)
|
||||
ARMv8::DumpJson (TraceOut);
|
||||
}
|
||||
|
|
120
Memory.cpp
120
Memory.cpp
|
@ -2,7 +2,7 @@
|
|||
#include <sys/mman.h>
|
||||
#include "Nsemu.hpp"
|
||||
|
||||
RAMBlock::RAMBlock (std::string _name, uint64_t _addr, size_t _length, int _perm) {
|
||||
RAMBlock::RAMBlock (std::string _name, uint64_t _addr, size_t _length, int _perm) : block(nullptr){
|
||||
int page = getpagesize ();
|
||||
name = _name;
|
||||
length = _length;
|
||||
|
@ -12,14 +12,28 @@ RAMBlock::RAMBlock (std::string _name, uint64_t _addr, size_t _length, int _perm
|
|||
}
|
||||
addr = _addr;
|
||||
}
|
||||
RAMBlock::RAMBlock(std::string _name, uint64_t _addr, size_t _length, uint8_t *raw, int _perm) {
|
||||
int page = getpagesize ();
|
||||
name = _name;
|
||||
length = _length;
|
||||
perm = _perm;
|
||||
if (addr & (page - 1)) {
|
||||
addr = addr & ~(page - 1);
|
||||
}
|
||||
addr = _addr;
|
||||
block = raw;
|
||||
}
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
uint64_t heap_base = 0x9000000;
|
||||
uint64_t heap_size = 0x2000000;
|
||||
uint64_t heap_size = 0x1000000;
|
||||
//uint64_t heap_size = 0x0;
|
||||
uint8_t *pRAM; // XXX: Replace raw pointer to View wrapper.
|
||||
static RAMBlock mem_map[] =
|
||||
size_t ram_size = 0x10000000;
|
||||
uint64_t straight_max = heap_base + heap_size;
|
||||
std::vector<RAMBlock*> regions;
|
||||
static RAMBlock mem_map_straight[] =
|
||||
{
|
||||
RAMBlock (".text", 0x0, 0x1000000, PROT_READ | PROT_WRITE | PROT_EXEC),
|
||||
RAMBlock (".rdata", 0x1000000, 0x1000000, PROT_READ | PROT_WRITE),
|
||||
|
@ -28,33 +42,79 @@ static RAMBlock mem_map[] =
|
|||
RAMBlock ("[heap]", heap_base, heap_size, PROT_READ | PROT_WRITE),
|
||||
};
|
||||
|
||||
static bool inline IsStraight(uint64_t addr, size_t len) {
|
||||
return addr + len <= straight_max;
|
||||
}
|
||||
|
||||
static RAMBlock* FindRamBlock(uint64_t addr, size_t len) {
|
||||
for (int i = 0; i < regions.size(); i++) {
|
||||
if (regions[i]->addr <= addr && addr + len <= regions[i]->addr + regions[i]->length) {
|
||||
return regions[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void AddAnonStraight(uint64_t addr, size_t len, int perm) {
|
||||
//ns_print("Add anonymous fixed region [0x%lx, %d]\n", addr, len);
|
||||
RAMBlock *new_ram = new RAMBlock("[anon]", addr, len, perm) ;
|
||||
regions.push_back(new_ram);
|
||||
}
|
||||
|
||||
static void AddAnonRamBlock(uint64_t addr, size_t len, int perm) {
|
||||
uint8_t *raw = new uint8_t[len];
|
||||
if (!raw) {
|
||||
ns_abort("Failed to allocate new RAM Block\n");
|
||||
}
|
||||
RAMBlock *new_ram = new RAMBlock("[anon]", addr, len, raw, perm);
|
||||
//ns_print("Add anonymous region [0x%lx, %d]\n", new_ram->addr, new_ram->length);
|
||||
regions.push_back(new_ram);
|
||||
}
|
||||
|
||||
void AddMemmap(uint64_t addr, size_t len) {
|
||||
if (IsStraight(addr, len)) {
|
||||
/* Within straight regions */
|
||||
AddAnonStraight(addr, len, PROT_READ | PROT_WRITE);
|
||||
return;
|
||||
}
|
||||
// if (ExistOverlap(addr, len))
|
||||
/* TODO Detect overlapped areas */
|
||||
|
||||
/* Necessary to extend memory area */
|
||||
AddAnonRamBlock(addr, len, PROT_READ | PROT_WRITE);
|
||||
}
|
||||
|
||||
void DelMemmap(uint64_t addr, size_t len) {
|
||||
auto it = regions.begin();
|
||||
while (it != regions.end()) {
|
||||
RAMBlock *ram = *it;
|
||||
if (addr <= ram->addr && ram->addr + ram->length <= addr + len) {
|
||||
delete ram;
|
||||
it = regions.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitMemmap(Nsemu *nsemu) {
|
||||
void *data;
|
||||
if ((data = mmap (nullptr, 0x10000000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) {
|
||||
if ((data = mmap (nullptr, ram_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) {
|
||||
ns_abort ("Failed to allocate host memory\n");
|
||||
}
|
||||
pRAM = (uint8_t *) data;
|
||||
}
|
||||
|
||||
RAMBlock *FindRAMBlock(Nsemu *nsemu, uint64_t addr, size_t len) {
|
||||
RAMBlock *as;
|
||||
std::map<std::string, RAMBlock>::iterator it = nsemu->rams.begin ();
|
||||
for (; it != nsemu->rams.end (); it++) {
|
||||
as = &it->second;
|
||||
if (as->addr <= addr && addr + len <= as->addr + as->length) {
|
||||
return as;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
for (int i = 0; i < sizeof(mem_map_straight) / sizeof(RAMBlock); i++) {
|
||||
regions.push_back(&mem_map_straight[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::list<std::tuple<uint64_t,uint64_t, int>> GetRegions() {
|
||||
std::list<std::tuple<uint64_t,uint64_t, int>> ret;
|
||||
uint64_t last;
|
||||
for (int i = 0; i < sizeof(mem_map) / sizeof(RAMBlock); i++) {
|
||||
uint64_t addr = mem_map[i].addr;
|
||||
size_t length = mem_map[i].length;
|
||||
int perm = mem_map[i].perm;
|
||||
for (int i = 0; i < regions.size(); i++) {
|
||||
uint64_t addr = regions[i]->addr;
|
||||
size_t length = regions[i]->length;
|
||||
int perm = regions[i]->perm;
|
||||
ret.push_back(make_tuple(addr, addr + length, perm));
|
||||
last = addr + length + 1;
|
||||
}
|
||||
|
@ -62,8 +122,26 @@ std::list<std::tuple<uint64_t,uint64_t, int>> GetRegions() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
void *GetRawPtr(uint64_t gpa, size_t len) {
|
||||
void *emu_mem;
|
||||
if (IsStraight(gpa, len)) {
|
||||
emu_mem = (void *)&pRAM[gpa];
|
||||
}
|
||||
else {
|
||||
RAMBlock *ram = FindRamBlock (gpa, len);
|
||||
if (!ram) {
|
||||
return nullptr;
|
||||
}
|
||||
emu_mem = (void *)&ram->block[gpa - ram->addr];
|
||||
}
|
||||
return emu_mem;
|
||||
}
|
||||
|
||||
static bool _CopyMemEmu(void *data, uint64_t gpa, size_t len, bool load) {
|
||||
void *emu_mem = (void *)&pRAM[gpa];
|
||||
void *emu_mem = GetRawPtr (gpa, len);
|
||||
if (!emu_mem) {
|
||||
return false;
|
||||
}
|
||||
if (load) {
|
||||
memcpy (emu_mem, data, len);
|
||||
} else {
|
||||
|
|
|
@ -41,11 +41,12 @@ int Nso::load(Nsemu *nsemu) {
|
|||
ns_abort ("Failed to copy to .text\n");
|
||||
}
|
||||
/* --- For test --- */
|
||||
// uint8_t *txt_dump = new uint8_t[hdr.textSize];
|
||||
// Memory::CopyfromEmuByName (nsemu, (void *) txt_dump, ".text", hdr.textSize);
|
||||
// bindump (txt_dump, 105);
|
||||
// /* ---------------- */
|
||||
// delete[] text;
|
||||
uint8_t *txt_dump = new uint8_t[hdr.textSize];
|
||||
Memory::CopyfromEmu (nsemu, (void *) txt_dump, base + hdr.textLoc, hdr.textSize);
|
||||
bindump ((uint8_t*)text, 105);
|
||||
bindump (txt_dump, 105);
|
||||
/* ---------------- */
|
||||
delete[] text;
|
||||
ns_print(".text[0x%x] size = 0x%x\n", hdr.textOff, hdr.textSize);
|
||||
ns_print(".rdata[0x%x] size = 0x%x\n", hdr.rdataOff, hdr.rdataSize);
|
||||
ns_print(".data[0x%x] size = 0x%x\n", hdr.dataOff, hdr.dataSize);
|
||||
|
|
14
Svc.cpp
14
Svc.cpp
|
@ -113,10 +113,24 @@ uint64_t SetMemoryAttribute(uint64_t addr, uint64_t size, uint64_t state0, uint6
|
|||
}
|
||||
|
||||
uint64_t MirrorStack(uint64_t dest, uint64_t src, uint64_t size) {
|
||||
ns_print("MirrorStack 0x%lx 0x%lx 0x%lx\n", dest, src, size);
|
||||
Memory::AddMemmap (dest, size);
|
||||
uint8_t *temp = new uint8_t[size];
|
||||
ARMv8::ReadBytes(src, temp, size);
|
||||
bindump(temp, size / 10);
|
||||
ns_print("#############\n");
|
||||
ARMv8::WriteBytes(dest, temp, size);
|
||||
ns_print("hoge\n");
|
||||
ARMv8::ReadBytes(dest, temp, size);
|
||||
bindump(temp, size / 10);
|
||||
ns_print("#############\n");
|
||||
delete[] temp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t UnmapMemory(uint64_t dest, uint64_t src, uint64_t size) {
|
||||
ns_print("UnmapMemory 0x%lx 0x%lx 0x%lx\n", dest, src, size);
|
||||
Memory::DelMemmap(dest, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,15 @@ std::string name;
|
|||
size_t length;
|
||||
int perm;
|
||||
uint64_t addr; //gpa (guest physical address)
|
||||
RAMBlock() {}
|
||||
RAMBlock(std::string _name, uint64_t _addr, size_t _length, int _perm);
|
||||
uint8_t *block;
|
||||
RAMBlock() { block = nullptr; }
|
||||
RAMBlock(std::string _name, uint64_t _addr, size_t _length, int _perm); //straight mapping
|
||||
RAMBlock(std::string _name, uint64_t _addr, size_t _length, uint8_t *raw, int _perm);
|
||||
~RAMBlock() {
|
||||
if (block) {
|
||||
delete[] block;
|
||||
}
|
||||
}
|
||||
bool operator<(const RAMBlock &as) {
|
||||
return name < as.name;
|
||||
}
|
||||
|
@ -27,12 +34,14 @@ extern uint64_t heap_base;
|
|||
extern uint64_t heap_size;
|
||||
|
||||
void InitMemmap(Nsemu *nsemu);
|
||||
RAMBlock *FindRAMBlock(Nsemu *nsemu, uint64_t addr, size_t len);
|
||||
void AddMemmap(uint64_t addr, size_t len);
|
||||
void DelMemmap(uint64_t addr, size_t len);
|
||||
std::list<std::tuple<uint64_t,uint64_t, int>> GetRegions();
|
||||
|
||||
void *GetRawPtr(uint64_t gpa, size_t len);
|
||||
bool CopytoEmu(Nsemu *nsemu, void *data, uint64_t addr, size_t len);
|
||||
bool CopytoEmuByName(Nsemu *nsemu, void *data, std::string name, size_t len);
|
||||
bool CopyfromEmu(Nsemu *nsemu, void *data, uint64_t addr, size_t len);
|
||||
bool CopyfromEmuByName(Nsemu *nsemu, void *data, std::string name, size_t len);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -39,7 +39,6 @@ Nsemu() = default;
|
|||
|
||||
static Nsemu *inst;
|
||||
public:
|
||||
std::map<std::string, RAMBlock> rams;
|
||||
public:
|
||||
Nsemu(const Nsemu&) = delete;
|
||||
Nsemu& operator=(const Nsemu&) = delete;
|
||||
|
|
|
@ -39,16 +39,16 @@ static void util_print(RunLevel level, FILE *fp, const char *format, ...) {
|
|||
inline void bindump(uint8_t *ptr, size_t size) {
|
||||
int i = 0;
|
||||
while (i < size) {
|
||||
debug_print ("%02x", ptr[i]);
|
||||
ns_print ("%02x", ptr[i]);
|
||||
if ((i + 1) % LINE_BREAK == 0) {
|
||||
debug_print ("\n");
|
||||
ns_print ("\n");
|
||||
} else {
|
||||
debug_print (" ");
|
||||
ns_print (" ");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i % LINE_BREAK != 0) {
|
||||
debug_print ("\n");
|
||||
ns_print ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue