Skip to content

Commit 2900995

Browse files
committed
uc_mem_write_virtual
need tests and rebase
1 parent 013877e commit 2900995

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

include/unicorn/unicorn.h

+4
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,10 @@ UNICORN_EXPORT
954954
uc_err uc_mem_read_virtual(uc_engine *uc, uint64_t address, uint32_t prot,
955955
void *bytes, size_t size);
956956

957+
UNICORN_EXPORT
958+
uc_err uc_mem_write_virtual(uc_engine *uc, uint64_t address, uint32_t prot,
959+
void *bytes, size_t size);
960+
957961
/*
958962
Translate a virtuall address to a physical address
959963

uc.c

+51
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,57 @@ uc_err uc_mem_read_virtual(uc_engine *uc, uint64_t address, uc_prot prot,
852852
return UC_ERR_OK;
853853
}
854854

855+
UNICORN_EXPORT
856+
uc_err uc_mem_write_virtual(uc_engine *uc, uint64_t address, uc_prot prot,
857+
void *_bytes, size_t size)
858+
{
859+
size_t count = 0, len;
860+
uint8_t *bytes = _bytes;
861+
uint64_t align;
862+
uint64_t pagesize;
863+
uint64_t paddr = 0;
864+
865+
UC_INIT(uc);
866+
867+
// qemu cpu_physical_memory_rw() size is an int
868+
if (size > INT_MAX) {
869+
restore_jit_state(uc);
870+
return UC_ERR_ARG;
871+
}
872+
873+
// The sparc mmu doesn't support probe mode
874+
if (uc->arch == UC_ARCH_SPARC && uc->cpu->cc->tlb_fill == uc->cpu->cc->tlb_fill_cpu) {
875+
restore_jit_state(uc);
876+
return UC_ERR_ARG;
877+
}
878+
879+
if (!(UC_PROT_READ == prot || UC_PROT_WRITE == prot ||
880+
UC_PROT_EXEC == prot)) {
881+
restore_jit_state(uc);
882+
return UC_ERR_ARG;
883+
}
884+
885+
while (count < size) {
886+
align = uc->target_page_align;
887+
pagesize = uc->target_page_size;
888+
len = MIN(size - count, (address & ~align) + pagesize - address);
889+
if (!uc_virtual_to_physical(uc, address, prot, &paddr)) {
890+
restore_jit_state(uc);
891+
return UC_ERR_WRITE_PROT;
892+
}
893+
if (!uc_mem_write(uc, paddr, bytes, len)) {
894+
restore_jit_state(uc);
895+
return UC_ERR_WRITE_PROT;
896+
}
897+
bytes += len;
898+
address += len;
899+
count += len;
900+
}
901+
assert(count == size);
902+
restore_jit_state(uc);
903+
return UC_ERR_OK;
904+
}
905+
855906
UNICORN_EXPORT
856907
uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size)
857908
{

0 commit comments

Comments
 (0)