intermediate commit, working unmap of complete blocks, still need sub-blocks, and cross block

This commit is contained in:
Chris Eagle 2015-08-29 21:17:30 -07:00
parent 160033c36c
commit 6beb1b8a13
18 changed files with 147 additions and 59 deletions

View File

@ -47,6 +47,8 @@ typedef void (*uc_args_uc_u64_t)(struct uc_struct *, uint64_t addr);
typedef MemoryRegion* (*uc_args_uc_ram_size_t)(struct uc_struct*, ram_addr_t begin, size_t size, uint32_t perms); typedef MemoryRegion* (*uc_args_uc_ram_size_t)(struct uc_struct*, ram_addr_t begin, size_t size, uint32_t perms);
typedef void (*uc_mem_unmap_t)(struct uc_struct*, MemoryRegion *mr);
typedef void (*uc_readonly_mem_t)(MemoryRegion *mr, bool readonly); typedef void (*uc_readonly_mem_t)(MemoryRegion *mr, bool readonly);
// which interrupt should make emulation stop? // which interrupt should make emulation stop?
@ -90,6 +92,7 @@ struct uc_struct {
uc_args_tcg_enable_t tcg_enabled; uc_args_tcg_enable_t tcg_enabled;
uc_args_uc_long_t tcg_exec_init; uc_args_uc_long_t tcg_exec_init;
uc_args_uc_ram_size_t memory_map; uc_args_uc_ram_size_t memory_map;
uc_mem_unmap_t memory_unmap;
uc_readonly_mem_t readonly_mem; uc_readonly_mem_t readonly_mem;
// list of cpu // list of cpu
void* cpu; void* cpu;

View File

@ -422,9 +422,9 @@ uc_err uc_mem_map(uch handle, uint64_t address, size_t size, uint32_t perms);
This API changes permissions on an existing memory region. This API changes permissions on an existing memory region.
@handle: handle returned by uc_open() @handle: handle returned by uc_open()
@start: starting address of the memory region to be modified. @address: starting address of the memory region to be modified.
This address must be aligned to 4KB, or this will return with UC_ERR_MAP error. This address must be aligned to 4KB, or this will return with UC_ERR_MAP error.
@block_size: size of the memory region to be modified. @size: size of the memory region to be modified.
This size must be multiple of 4KB, or this will return with UC_ERR_MAP error. This size must be multiple of 4KB, or this will return with UC_ERR_MAP error.
@perms: New permissions for the mapped region. @perms: New permissions for the mapped region.
This must be some combination of UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC, This must be some combination of UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC,
@ -434,7 +434,23 @@ uc_err uc_mem_map(uch handle, uint64_t address, size_t size, uint32_t perms);
for detailed error). for detailed error).
*/ */
UNICORN_EXPORT UNICORN_EXPORT
uc_err uc_mem_protect(uch handle, uint64_t start, size_t block_size, uint32_t perms); uc_err uc_mem_protect(uch handle, uint64_t address, size_t size, uint32_t perms);
/*
Unmap a region of emulation memory.
This API deletes a memory mapping from the emulation memory space.
@handle: handle returned by uc_open()
@address: starting address of the memory region to be unmapped.
This address must be aligned to 4KB, or this will return with UC_ERR_MAP error.
@size: size of the memory region to be modified.
This size must be multiple of 4KB, or this will return with UC_ERR_MAP error.
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_mem_unmap(uch handle, uint64_t address, size_t size);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_aarch64 #define phys_mem_clean phys_mem_clean_aarch64
#define tb_cleanup tb_cleanup_aarch64 #define tb_cleanup tb_cleanup_aarch64
#define memory_map memory_map_aarch64 #define memory_map memory_map_aarch64
#define memory_unmap memory_unmap_aarch64
#define memory_free memory_free_aarch64 #define memory_free memory_free_aarch64
#define helper_raise_exception helper_raise_exception_aarch64 #define helper_raise_exception helper_raise_exception_aarch64
#define tcg_enabled tcg_enabled_aarch64 #define tcg_enabled tcg_enabled_aarch64

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_arm #define phys_mem_clean phys_mem_clean_arm
#define tb_cleanup tb_cleanup_arm #define tb_cleanup tb_cleanup_arm
#define memory_map memory_map_arm #define memory_map memory_map_arm
#define memory_unmap memory_unmap_arm
#define memory_free memory_free_arm #define memory_free memory_free_arm
#define helper_raise_exception helper_raise_exception_arm #define helper_raise_exception helper_raise_exception_arm
#define tcg_enabled tcg_enabled_arm #define tcg_enabled tcg_enabled_arm

View File

@ -13,6 +13,7 @@ symbols = (
'phys_mem_clean', 'phys_mem_clean',
'tb_cleanup', 'tb_cleanup',
'memory_map', 'memory_map',
'memory_unmap',
'memory_free', 'memory_free',
'helper_raise_exception', 'helper_raise_exception',
'tcg_enabled', 'tcg_enabled',

View File

@ -939,6 +939,7 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
void memory_register_types(struct uc_struct *uc); void memory_register_types(struct uc_struct *uc);
MemoryRegion *memory_map(struct uc_struct *uc, ram_addr_t begin, size_t size, uint32_t perms); MemoryRegion *memory_map(struct uc_struct *uc, ram_addr_t begin, size_t size, uint32_t perms);
void memory_unmap(struct uc_struct *uc, MemoryRegion *mr);
int memory_free(struct uc_struct *uc); int memory_free(struct uc_struct *uc);
#endif #endif

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_m68k #define phys_mem_clean phys_mem_clean_m68k
#define tb_cleanup tb_cleanup_m68k #define tb_cleanup tb_cleanup_m68k
#define memory_map memory_map_m68k #define memory_map memory_map_m68k
#define memory_unmap memory_unmap_m68k
#define memory_free memory_free_m68k #define memory_free memory_free_m68k
#define helper_raise_exception helper_raise_exception_m68k #define helper_raise_exception helper_raise_exception_m68k
#define tcg_enabled tcg_enabled_m68k #define tcg_enabled tcg_enabled_m68k

View File

@ -45,6 +45,18 @@ MemoryRegion *memory_map(struct uc_struct *uc, ram_addr_t begin, size_t size, ui
return uc->ram; return uc->ram;
} }
void memory_unmap(struct uc_struct *uc, MemoryRegion *mr)
{
targer_ulong addr;
//make sure all pages associated with the MemoryRegion are flushed
for (addr = mr->addr; addr < mr->end; addr += 0x1000) {
tlb_flush_page(uc->current_cpu, addr);
}
mr->enabled = false;
memory_region_del_subregion(get_system_memory(uc), mr);
g_free(mr);
}
int memory_free(struct uc_struct *uc) int memory_free(struct uc_struct *uc)
{ {
int i; int i;

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_mips #define phys_mem_clean phys_mem_clean_mips
#define tb_cleanup tb_cleanup_mips #define tb_cleanup tb_cleanup_mips
#define memory_map memory_map_mips #define memory_map memory_map_mips
#define memory_unmap memory_unmap_mips
#define memory_free memory_free_mips #define memory_free memory_free_mips
#define helper_raise_exception helper_raise_exception_mips #define helper_raise_exception helper_raise_exception_mips
#define tcg_enabled tcg_enabled_mips #define tcg_enabled tcg_enabled_mips

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_mips64 #define phys_mem_clean phys_mem_clean_mips64
#define tb_cleanup tb_cleanup_mips64 #define tb_cleanup tb_cleanup_mips64
#define memory_map memory_map_mips64 #define memory_map memory_map_mips64
#define memory_unmap memory_unmap_mips64
#define memory_free memory_free_mips64 #define memory_free memory_free_mips64
#define helper_raise_exception helper_raise_exception_mips64 #define helper_raise_exception helper_raise_exception_mips64
#define tcg_enabled tcg_enabled_mips64 #define tcg_enabled tcg_enabled_mips64

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_mips64el #define phys_mem_clean phys_mem_clean_mips64el
#define tb_cleanup tb_cleanup_mips64el #define tb_cleanup tb_cleanup_mips64el
#define memory_map memory_map_mips64el #define memory_map memory_map_mips64el
#define memory_unmap memory_unmap_mips64el
#define memory_free memory_free_mips64el #define memory_free memory_free_mips64el
#define helper_raise_exception helper_raise_exception_mips64el #define helper_raise_exception helper_raise_exception_mips64el
#define tcg_enabled tcg_enabled_mips64el #define tcg_enabled tcg_enabled_mips64el

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_mipsel #define phys_mem_clean phys_mem_clean_mipsel
#define tb_cleanup tb_cleanup_mipsel #define tb_cleanup tb_cleanup_mipsel
#define memory_map memory_map_mipsel #define memory_map memory_map_mipsel
#define memory_unmap memory_unmap_mipsel
#define memory_free memory_free_mipsel #define memory_free memory_free_mipsel
#define helper_raise_exception helper_raise_exception_mipsel #define helper_raise_exception helper_raise_exception_mipsel
#define tcg_enabled tcg_enabled_mipsel #define tcg_enabled tcg_enabled_mipsel

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_powerpc #define phys_mem_clean phys_mem_clean_powerpc
#define tb_cleanup tb_cleanup_powerpc #define tb_cleanup tb_cleanup_powerpc
#define memory_map memory_map_powerpc #define memory_map memory_map_powerpc
#define memory_unmap memory_unmap_powerpc
#define memory_free memory_free_powerpc #define memory_free memory_free_powerpc
#define helper_raise_exception helper_raise_exception_powerpc #define helper_raise_exception helper_raise_exception_powerpc
#define tcg_enabled tcg_enabled_powerpc #define tcg_enabled tcg_enabled_powerpc

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_sparc #define phys_mem_clean phys_mem_clean_sparc
#define tb_cleanup tb_cleanup_sparc #define tb_cleanup tb_cleanup_sparc
#define memory_map memory_map_sparc #define memory_map memory_map_sparc
#define memory_unmap memory_unmap_sparc
#define memory_free memory_free_sparc #define memory_free memory_free_sparc
#define helper_raise_exception helper_raise_exception_sparc #define helper_raise_exception helper_raise_exception_sparc
#define tcg_enabled tcg_enabled_sparc #define tcg_enabled tcg_enabled_sparc

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_sparc64 #define phys_mem_clean phys_mem_clean_sparc64
#define tb_cleanup tb_cleanup_sparc64 #define tb_cleanup tb_cleanup_sparc64
#define memory_map memory_map_sparc64 #define memory_map memory_map_sparc64
#define memory_unmap memory_unmap_sparc64
#define memory_free memory_free_sparc64 #define memory_free memory_free_sparc64
#define helper_raise_exception helper_raise_exception_sparc64 #define helper_raise_exception helper_raise_exception_sparc64
#define tcg_enabled tcg_enabled_sparc64 #define tcg_enabled tcg_enabled_sparc64

View File

@ -73,6 +73,7 @@ static inline void uc_common_init(struct uc_struct* uc)
uc->pause_all_vcpus = pause_all_vcpus; uc->pause_all_vcpus = pause_all_vcpus;
uc->vm_start = vm_start; uc->vm_start = vm_start;
uc->memory_map = memory_map; uc->memory_map = memory_map;
uc->memory_unmap = memory_unmap;
uc->readonly_mem = memory_region_set_readonly; uc->readonly_mem = memory_region_set_readonly;
if (!uc->release) if (!uc->release)

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_x86_64 #define phys_mem_clean phys_mem_clean_x86_64
#define tb_cleanup tb_cleanup_x86_64 #define tb_cleanup tb_cleanup_x86_64
#define memory_map memory_map_x86_64 #define memory_map memory_map_x86_64
#define memory_unmap memory_unmap_x86_64
#define memory_free memory_free_x86_64 #define memory_free memory_free_x86_64
#define helper_raise_exception helper_raise_exception_x86_64 #define helper_raise_exception helper_raise_exception_x86_64
#define tcg_enabled tcg_enabled_x86_64 #define tcg_enabled tcg_enabled_x86_64

95
uc.c
View File

@ -643,55 +643,46 @@ uc_err uc_mem_map(uch handle, uint64_t address, size_t size, uint32_t perms)
} }
UNICORN_EXPORT UNICORN_EXPORT
uc_err uc_mem_protect(uch handle, uint64_t start, size_t block_size, uint32_t perms) uc_err uc_mem_protect(uch handle, uint64_t address, size_t size, uint32_t perms)
{ {
uint64_t address;
uint64_t size;
struct uc_struct* uc = (struct uc_struct *)handle; struct uc_struct* uc = (struct uc_struct *)handle;
MemoryRegion *mr;
if (handle == 0) if (handle == 0)
// invalid handle // invalid handle
return UC_ERR_UCH; return UC_ERR_UCH;
if (block_size == 0) if (size == 0)
// invalid memory mapping // invalid memory mapping
return UC_ERR_MAP; return UC_ERR_MAP;
// address must be aligned to 4KB // address must be aligned to 4KB
if ((start & (4*1024 - 1)) != 0) if ((address & (4*1024 - 1)) != 0)
return UC_ERR_MAP; return UC_ERR_MAP;
// size must be multiple of 4KB // size must be multiple of 4KB
if ((block_size & (4*1024 - 1)) != 0) if ((size & (4*1024 - 1)) != 0)
return UC_ERR_MAP; return UC_ERR_MAP;
// check for only valid permissions // check for only valid permissions
if ((perms & ~(UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC)) != 0) if ((perms & ~(UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC)) != 0)
return UC_ERR_MAP; return UC_ERR_MAP;
//check that users entire requested block is mapped //check that user's entire requested block is mapped
address = start; if (!check_mem_area(uc, address, size))
size = block_size;
while (size > 0) {
uint64_t region_size;
MemoryRegion *mr = memory_mapping(uc, address);
if (mr == NULL) {
return UC_ERR_MAP; return UC_ERR_MAP;
}
region_size = int128_get64(mr->size);
if (address > mr->addr) {
//in case start address is not aligned with start of region
region_size -= address - mr->addr;
}
if (size < region_size) {
//entire region is covered
break;
}
size -= region_size;
address += region_size;
}
//Now we know entire region is mapped, so change permissions //Now we know entire region is mapped, so change permissions
//check trivial case first
mr = memory_mapping(uc, address);
if (address == mr->addr && size == int128_get64(mr->size)) {
//regions exactly matches an existing region just change perms
mr->perms = perms;
uc->readonly_mem(mr, (perms & UC_PROT_WRITE) == 0);
}
else {
//ouch, we are going to need to subdivide blocks
/*
address = start; address = start;
size = block_size; size = block_size;
while (size > 0) { while (size > 0) {
@ -723,9 +714,61 @@ uc_err uc_mem_protect(uch handle, uint64_t start, size_t block_size, uint32_t pe
mr->perms = perms; mr->perms = perms;
uc->readonly_mem(mr, (perms & UC_PROT_WRITE) == 0); uc->readonly_mem(mr, (perms & UC_PROT_WRITE) == 0);
} }
*/
}
return UC_ERR_OK; return UC_ERR_OK;
} }
UNICORN_EXPORT
uc_err uc_mem_unmap(uch handle, uint64_t address, size_t size)
{
MemoryRegion *mr;
unsigned int i;
struct uc_struct* uc = (struct uc_struct *)handle;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
if (size == 0)
// nothing to unmap
return UC_ERR_OK;
// address must be aligned to 4KB
if ((address & (4*1024 - 1)) != 0)
return UC_ERR_MAP;
// size must be multiple of 4KB
if ((size & (4*1024 - 1)) != 0)
return UC_ERR_MAP;
//check that user's entire requested block is mapped
if (!check_mem_area(uc, address, size))
return UC_ERR_MAP;
//Now we know entire region is mapped, so change permissions
//check trivial case first
mr = memory_mapping(uc, address);
if (address == mr->addr && size == int128_get64(mr->size)) {
//regions exactly matches an existing region just unmap it
uc->memory_unmap(uc, mr);
for (i = 0; i < uc->mapped_block_count; i++) {
if (uc->mapped_blocks[i] == mr) {
uc->mapped_block_count--;
//shift remainder of array down over deleted pointer
memcpy(&uc->mapped_blocks[i], &uc->mapped_blocks[i + 1], sizeof(MemoryRegion*) * (uc->mapped_block_count - i));
break;
}
}
return UC_ERR_OK;
}
else {
//ouch, we are going to need to subdivide blocks
}
return UC_ERR_MAP;
}
MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address) MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address)
{ {
unsigned int i; unsigned int i;