tests/A64: Unicorn interface fixes
- Use a std::unique_ptr instead of new/delete. - UnmappedMemoryHook: Correct range when wraparound of the address space occurs - UnmappedMemoryHook: Handle case when we attempt to map the same page twice
This commit is contained in:
parent
d5725de26a
commit
39d083aa87
2 changed files with 23 additions and 11 deletions
|
@ -29,7 +29,6 @@ Unicorn::Unicorn(TestEnv& testenv) : testenv(testenv) {
|
||||||
Unicorn::~Unicorn() {
|
Unicorn::~Unicorn() {
|
||||||
for (const auto& page : pages) {
|
for (const auto& page : pages) {
|
||||||
CHECKED(uc_mem_unmap(uc, page->address, 4096));
|
CHECKED(uc_mem_unmap(uc, page->address, 4096));
|
||||||
delete page;
|
|
||||||
}
|
}
|
||||||
CHECKED(uc_hook_del(uc, intr_hook));
|
CHECKED(uc_hook_del(uc, intr_hook));
|
||||||
CHECKED(uc_hook_del(uc, mem_invalid_hook));
|
CHECKED(uc_hook_del(uc, mem_invalid_hook));
|
||||||
|
@ -171,29 +170,42 @@ void Unicorn::InterruptHook(uc_engine* uc, u32, void* user_data) {
|
||||||
bool Unicorn::UnmappedMemoryHook(uc_engine* uc, uc_mem_type /*type*/, u64 start_address, int size, u64 /*value*/, void* user_data) {
|
bool Unicorn::UnmappedMemoryHook(uc_engine* uc, uc_mem_type /*type*/, u64 start_address, int size, u64 /*value*/, void* user_data) {
|
||||||
Unicorn* this_ = reinterpret_cast<Unicorn*>(user_data);
|
Unicorn* this_ = reinterpret_cast<Unicorn*>(user_data);
|
||||||
|
|
||||||
const auto generate_page = [&](u64 base_address) -> Page* {
|
const auto generate_page = [&](u64 base_address) {
|
||||||
printf("generate_page(%" PRIx64 ")\n", base_address);
|
printf("generate_page(%" PRIx64 ")\n", base_address);
|
||||||
|
|
||||||
const u32 permissions = [&]{
|
const u32 permissions = [&]{
|
||||||
if (base_address < this_->testenv.code_mem.size() * 4)
|
if (base_address < this_->testenv.code_mem.size() * 4)
|
||||||
return UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC;
|
return UC_PROT_READ | UC_PROT_EXEC;
|
||||||
return UC_PROT_READ | UC_PROT_WRITE;
|
return UC_PROT_READ | UC_PROT_WRITE;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
auto page = new Page();
|
auto page = std::make_unique<Page>();
|
||||||
page->address = base_address;
|
page->address = base_address;
|
||||||
for (size_t i = 0; i < page->data.size(); ++i)
|
for (size_t i = 0; i < page->data.size(); ++i)
|
||||||
page->data[i] = this_->testenv.MemoryRead8(base_address + i);
|
page->data[i] = this_->testenv.MemoryRead8(base_address + i);
|
||||||
CHECKED(uc_mem_map_ptr(uc, base_address, page->data.size(), permissions, page->data.data()));
|
|
||||||
return page;
|
uc_err err = uc_mem_map_ptr(uc, base_address, page->data.size(), permissions, page->data.data());
|
||||||
|
if (err == UC_ERR_MAP)
|
||||||
|
return; // page already exists
|
||||||
|
CHECKED(err);
|
||||||
|
|
||||||
|
this_->pages.emplace_back(std::move(page));
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto is_in_range = [](u64 addr, u64 start, u64 end) {
|
||||||
|
if (start <= end)
|
||||||
|
return addr >= start && addr <= end; // fffff[tttttt]fffff
|
||||||
|
return addr >= start || addr <= end; // ttttt]ffffff[ttttt
|
||||||
};
|
};
|
||||||
|
|
||||||
const u64 start_address_page = start_address & ~u64(0xFFF);
|
const u64 start_address_page = start_address & ~u64(0xFFF);
|
||||||
const u64 end_address = start_address + size - 1;
|
const u64 end_address = start_address + size - 1;
|
||||||
generate_page(start_address_page);
|
|
||||||
for (u64 addr = start_address_page + 0x1000; addr <= end_address && addr >= start_address_page; addr += 0x1000) {
|
u64 current_address = start_address_page;
|
||||||
this_->pages.emplace_back(generate_page(addr));
|
do {
|
||||||
}
|
generate_page(current_address);
|
||||||
|
current_address += 0x1000;
|
||||||
|
} while (is_in_range(current_address, start_address_page, end_address) && current_address != start_address_page);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,5 +60,5 @@ private:
|
||||||
uc_hook intr_hook{};
|
uc_hook intr_hook{};
|
||||||
uc_hook mem_invalid_hook{};
|
uc_hook mem_invalid_hook{};
|
||||||
|
|
||||||
std::vector<Page*> pages;
|
std::vector<std::unique_ptr<Page>> pages;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue