This commit is contained in:

committed by
Nguyen Anh Quynh

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;
|
uint32_t perms;
|
||||||
uint64_t begin, end, chunk_end;
|
uint64_t begin, end, chunk_end;
|
||||||
size_t l_size, m_size, r_size;
|
size_t l_size, m_size, r_size;
|
||||||
|
RAMBlock *block = NULL;
|
||||||
|
bool prealloc = false;
|
||||||
|
|
||||||
chunk_end = address + size;
|
chunk_end = address + size;
|
||||||
|
|
||||||
@ -817,10 +819,27 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr, uint64_t addres
|
|||||||
// impossible case
|
// impossible case
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
backup = copy_region(uc, mr);
|
QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) {
|
||||||
if (backup == NULL)
|
if (block->offset <= mr->addr && block->length >= (mr->end - mr->addr)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block == NULL)
|
||||||
return false;
|
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
|
// save the essential information required for the split before mr gets deleted
|
||||||
perms = mr->perms;
|
perms = mr->perms;
|
||||||
begin = mr->addr;
|
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 just failed so no guarantee that we can recover the original
|
||||||
// allocation at this point
|
// allocation at this point
|
||||||
if (l_size > 0) {
|
if (l_size > 0) {
|
||||||
if (uc_mem_map(uc, begin, l_size, perms) != UC_ERR_OK)
|
if (!prealloc) {
|
||||||
goto error;
|
if (uc_mem_map(uc, begin, l_size, perms) != UC_ERR_OK)
|
||||||
if (uc_mem_write(uc, begin, backup, l_size) != UC_ERR_OK)
|
goto error;
|
||||||
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 (m_size > 0 && !do_delete) {
|
||||||
if (uc_mem_map(uc, address, m_size, perms) != UC_ERR_OK)
|
if (!prealloc) {
|
||||||
goto error;
|
if (uc_mem_map(uc, address, m_size, perms) != UC_ERR_OK)
|
||||||
if (uc_mem_write(uc, address, backup + l_size, m_size) != UC_ERR_OK)
|
goto error;
|
||||||
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 (r_size > 0) {
|
||||||
if (uc_mem_map(uc, chunk_end, r_size, perms) != UC_ERR_OK)
|
if (!prealloc) {
|
||||||
goto error;
|
if (uc_mem_map(uc, chunk_end, r_size, perms) != UC_ERR_OK)
|
||||||
if (uc_mem_write(uc, chunk_end, backup + l_size + m_size, r_size) != UC_ERR_OK)
|
goto error;
|
||||||
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;
|
return true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
free(backup);
|
if (!prealloc)
|
||||||
|
free(backup);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user