Skip to content

Commit 3ad58e1

Browse files
authored
Minor fixes for vmem apis (#2199)
* Minor fixes for vmem apis * Fix rust bindings Prot * Format bindings
1 parent 479b0c2 commit 3ad58e1

File tree

3 files changed

+51
-24
lines changed

3 files changed

+51
-24
lines changed

bindings/rust/src/lib.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,13 +330,36 @@ impl<'a, D> Unicorn<'a, D> {
330330

331331
/// Read a range of bytes from memory at the specified emulated virtual address.
332332
pub fn vmem_read(&self, address: u64, prot: Prot, buf: &mut [u8]) -> Result<(), uc_error> {
333-
unsafe { uc_vmem_read(self.get_handle(), address, prot.0 as _, buf.as_mut_ptr() as _, buf.len()) }.into()
333+
unsafe {
334+
uc_vmem_read(
335+
self.get_handle(),
336+
address,
337+
prot,
338+
buf.as_mut_ptr() as _,
339+
buf.len(),
340+
)
341+
}
342+
.into()
334343
}
335344

336345
/// Return a range of bytes from memory at the specified emulated virtual address as vector.
337-
pub fn vmem_read_as_vec(&self, address: u64, prot: Prot, size: usize) -> Result<Vec<u8>, uc_error> {
346+
pub fn vmem_read_as_vec(
347+
&self,
348+
address: u64,
349+
prot: Prot,
350+
size: usize,
351+
) -> Result<Vec<u8>, uc_error> {
338352
let mut buf = vec![0; size];
339-
unsafe { uc_vmem_read(self.get_handle(), address, prot.0 as _, buf.as_mut_ptr() as _, buf.len()) }.and(Ok(buf))
353+
unsafe {
354+
uc_vmem_read(
355+
self.get_handle(),
356+
address,
357+
prot,
358+
buf.as_mut_ptr() as _,
359+
buf.len(),
360+
)
361+
}
362+
.and(Ok(buf))
340363
}
341364

342365
/// Write the data in `bytes` to the emulated physical address `address`
@@ -355,7 +378,7 @@ impl<'a, D> Unicorn<'a, D> {
355378
/// translate virtual to physical address
356379
pub fn vmem_translate(&mut self, address: u64, prot: Prot) -> Result<u64, uc_error> {
357380
let mut physical: u64 = 0;
358-
let err = unsafe { uc_vmem_translate(self.get_handle(), address, prot.0 as _, &mut physical) };
381+
let err = unsafe { uc_vmem_translate(self.get_handle(), address, prot, &mut physical) };
359382
if err != uc_error::OK {
360383
return Err(err);
361384
}

include/unicorn/unicorn.h

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,22 @@ typedef uint32_t (*uc_cb_insn_in_t)(uc_engine *uc, uint32_t port, int size,
245245
typedef void (*uc_cb_insn_out_t)(uc_engine *uc, uint32_t port, int size,
246246
uint32_t value, void *user_data);
247247

248+
// The definitions for `uc_cb_tlbevent_t` callback
249+
typedef enum uc_prot {
250+
UC_PROT_NONE = 0,
251+
UC_PROT_READ = 1,
252+
UC_PROT_WRITE = 2,
253+
UC_PROT_EXEC = 4,
254+
UC_PROT_ALL = 7,
255+
} uc_prot;
256+
257+
struct uc_tlb_entry {
258+
uint64_t paddr;
259+
uc_prot perms;
260+
};
261+
248262
typedef struct uc_tlb_entry uc_tlb_entry;
263+
249264
// All type of memory accesses for UC_HOOK_MEM_*
250265
typedef enum uc_mem_type {
251266
UC_MEM_READ = 16, // Memory is read from
@@ -950,16 +965,16 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, uint64_t size);
950965
will not translate the virtual address when the pages are not mapped
951966
with the given access rights.
952967
953-
When the pages are mapped with the given access rights the read will
954-
happen indipenden from the access rights of the mapping. So when you
955-
have a page write only mapped, a call with prot == UC_PROT_WRITE will
956-
be able to read the stored data.
968+
Note the `prot` is different from the underlying protections of the physicall
969+
memory regions. For instance, if a region of phyiscal memory is mapped with
970+
write-only permissions, only a call with prot == UC_PROT_WRITE will be able to
971+
read the contents.
957972
958973
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
959974
for detailed error).
960975
*/
961976
UNICORN_EXPORT
962-
uc_err uc_vmem_read(uc_engine *uc, uint64_t address, uint32_t prot,
977+
uc_err uc_vmem_read(uc_engine *uc, uint64_t address, uc_prot prot,
963978
void *bytes, size_t size);
964979

965980
/*
@@ -987,7 +1002,7 @@ uc_err uc_vmem_read(uc_engine *uc, uint64_t address, uint32_t prot,
9871002
for detailed error).
9881003
*/
9891004
UNICORN_EXPORT
990-
uc_err uc_vmem_write(uc_engine *uc, uint64_t address, uint32_t prot,
1005+
uc_err uc_vmem_write(uc_engine *uc, uint64_t address, uc_prot prot,
9911006
void *bytes, size_t size);
9921007

9931008
/*
@@ -1007,7 +1022,7 @@ uc_err uc_vmem_write(uc_engine *uc, uint64_t address, uint32_t prot,
10071022
for detailed error).
10081023
*/
10091024
UNICORN_EXPORT
1010-
uc_err uc_vmem_translate(uc_engine *uc, uint64_t address, uint32_t prot,
1025+
uc_err uc_vmem_translate(uc_engine *uc, uint64_t address, uc_prot prot,
10111026
uint64_t *paddress);
10121027

10131028
/*
@@ -1088,19 +1103,6 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
10881103
UNICORN_EXPORT
10891104
uc_err uc_hook_del(uc_engine *uc, uc_hook hh);
10901105

1091-
typedef enum uc_prot {
1092-
UC_PROT_NONE = 0,
1093-
UC_PROT_READ = 1,
1094-
UC_PROT_WRITE = 2,
1095-
UC_PROT_EXEC = 4,
1096-
UC_PROT_ALL = 7,
1097-
} uc_prot;
1098-
1099-
struct uc_tlb_entry {
1100-
uint64_t paddr;
1101-
uc_prot perms;
1102-
};
1103-
11041106
/*
11051107
Variables to control which state should be stored in the context.
11061108
Defaults to UC_CTL_CONTEXT_CPU. The options are used in a bitfield

uc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,8 @@ uc_err uc_vmem_translate(uc_engine *uc, uint64_t address, uc_prot prot,
803803
return UC_ERR_WRITE_PROT;
804804
case UC_PROT_EXEC:
805805
return UC_ERR_FETCH_PROT;
806+
default:
807+
return UC_ERR_ARG;
806808
}
807809
}
808810

0 commit comments

Comments
 (0)