mirror of
https://github.com/Vita3K/unicorn.git
synced 2025-02-20 03:51:57 +00:00
This commit is contained in:
parent
d6d4131873
commit
d38c8fb27f
68
uc.c
68
uc.c
@ -801,6 +801,8 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr, uint64_t addres
|
||||
uint32_t perms;
|
||||
uint64_t begin, end, chunk_end;
|
||||
size_t l_size, m_size, r_size;
|
||||
RAMBlock *block = NULL;
|
||||
bool prealloc = false;
|
||||
|
||||
chunk_end = address + size;
|
||||
|
||||
@ -817,10 +819,27 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr, uint64_t addres
|
||||
// impossible case
|
||||
return false;
|
||||
|
||||
backup = copy_region(uc, mr);
|
||||
if (backup == NULL)
|
||||
QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) {
|
||||
if (block->offset <= mr->addr && block->length >= (mr->end - mr->addr)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (block == NULL)
|
||||
return false;
|
||||
|
||||
// RAM_PREALLOC is not defined outside exec.c and I didn't feel like
|
||||
// moving it
|
||||
prealloc = !!(block->flags & 1);
|
||||
|
||||
if (block->flags & 1) {
|
||||
backup = block->host;
|
||||
} else {
|
||||
backup = copy_region(uc, mr);
|
||||
if (backup == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
// save the essential information required for the split before mr gets deleted
|
||||
perms = mr->perms;
|
||||
begin = mr->addr;
|
||||
@ -853,31 +872,48 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr, uint64_t addres
|
||||
// allocation just failed so no guarantee that we can recover the original
|
||||
// allocation at this point
|
||||
if (l_size > 0) {
|
||||
if (uc_mem_map(uc, begin, l_size, perms) != UC_ERR_OK)
|
||||
goto error;
|
||||
if (uc_mem_write(uc, begin, backup, l_size) != UC_ERR_OK)
|
||||
goto error;
|
||||
if (!prealloc) {
|
||||
if (uc_mem_map(uc, begin, l_size, perms) != UC_ERR_OK)
|
||||
goto error;
|
||||
if (uc_mem_write(uc, begin, backup, l_size) != UC_ERR_OK)
|
||||
goto error;
|
||||
} else {
|
||||
if (uc_mem_map_ptr(uc, begin, l_size, perms, backup) != UC_ERR_OK)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_size > 0 && !do_delete) {
|
||||
if (uc_mem_map(uc, address, m_size, perms) != UC_ERR_OK)
|
||||
goto error;
|
||||
if (uc_mem_write(uc, address, backup + l_size, m_size) != UC_ERR_OK)
|
||||
goto error;
|
||||
if (!prealloc) {
|
||||
if (uc_mem_map(uc, address, m_size, perms) != UC_ERR_OK)
|
||||
goto error;
|
||||
if (uc_mem_write(uc, address, backup + l_size, m_size) != UC_ERR_OK)
|
||||
goto error;
|
||||
} else {
|
||||
if (uc_mem_map_ptr(uc, address, m_size, perms, backup + l_size) != UC_ERR_OK)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (r_size > 0) {
|
||||
if (uc_mem_map(uc, chunk_end, r_size, perms) != UC_ERR_OK)
|
||||
goto error;
|
||||
if (uc_mem_write(uc, chunk_end, backup + l_size + m_size, r_size) != UC_ERR_OK)
|
||||
goto error;
|
||||
if (!prealloc) {
|
||||
if (uc_mem_map(uc, chunk_end, r_size, perms) != UC_ERR_OK)
|
||||
goto error;
|
||||
if (uc_mem_write(uc, chunk_end, backup + l_size + m_size, r_size) != UC_ERR_OK)
|
||||
goto error;
|
||||
} else {
|
||||
if (uc_mem_map_ptr(uc, chunk_end, r_size, perms, backup + l_size + m_size) != UC_ERR_OK)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
free(backup);
|
||||
if (!prealloc)
|
||||
free(backup);
|
||||
return true;
|
||||
|
||||
error:
|
||||
free(backup);
|
||||
if (!prealloc)
|
||||
free(backup);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user