add batched reg access
This commit is contained in:
23
bindings/go/unicorn/uc.c
Normal file
23
bindings/go/unicorn/uc.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <stdlib.h>
|
||||
#include <unicorn/unicorn.h>
|
||||
#include "_cgo_export.h"
|
||||
|
||||
uc_err uc_reg_read_batch_helper(uc_engine *handle, int *regs, uint64_t *val_out, int count) {
|
||||
void **val_ref = malloc(sizeof(void *) * count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
val_ref[i] = (void *)&val_out[i];
|
||||
}
|
||||
uc_err ret = uc_reg_read_batch(handle, regs, val_ref, count);
|
||||
free(val_ref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uc_err uc_reg_write_batch_helper(uc_engine *handle, int *regs, uint64_t *val_in, int count) {
|
||||
const void **val_ref = malloc(sizeof(void *) * count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
val_ref[i] = (void *)&val_in[i];
|
||||
}
|
||||
uc_err ret = uc_reg_write_batch(handle, regs, val_ref, count);
|
||||
free(val_ref);
|
||||
return ret;
|
||||
}
|
2
bindings/go/unicorn/uc.h
Normal file
2
bindings/go/unicorn/uc.h
Normal file
@ -0,0 +1,2 @@
|
||||
uc_err uc_reg_read_batch_helper(uc_engine *handle, int *regs, uint64_t *val_out, int count);
|
||||
uc_err uc_reg_write_batch_helper(uc_engine *handle, int *regs, uint64_t *val_in, int count);
|
@ -7,8 +7,10 @@ import (
|
||||
)
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -O3
|
||||
#cgo LDFLAGS: -lunicorn
|
||||
#include <unicorn/unicorn.h>
|
||||
#include "uc.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
@ -41,7 +43,9 @@ type Unicorn interface {
|
||||
MemReadInto(dst []byte, addr uint64) error
|
||||
MemWrite(addr uint64, data []byte) error
|
||||
RegRead(reg int) (uint64, error)
|
||||
RegReadBatch(regs []int) ([]uint64, error)
|
||||
RegWrite(reg int, value uint64) error
|
||||
RegWriteBatch(regs []int, vals []uint64) error
|
||||
RegReadMmr(reg int) (*X86Mmr, error)
|
||||
RegWriteMmr(reg int, value *X86Mmr) error
|
||||
Start(begin, until uint64) error
|
||||
@ -117,6 +121,38 @@ func (u *uc) RegRead(reg int) (uint64, error) {
|
||||
return uint64(val), errReturn(ucerr)
|
||||
}
|
||||
|
||||
func (u *uc) RegWriteBatch(regs []int, vals []uint64) error {
|
||||
if len(regs) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(vals) < len(regs) {
|
||||
regs = regs[:len(vals)]
|
||||
}
|
||||
cregs := make([]C.int, len(regs))
|
||||
for i, v := range regs {
|
||||
cregs[i] = C.int(v)
|
||||
}
|
||||
cregs2 := (*C.int)(unsafe.Pointer(&cregs[0]))
|
||||
cvals := (*C.uint64_t)(unsafe.Pointer(&vals[0]))
|
||||
ucerr := C.uc_reg_write_batch_helper(u.handle, cregs2, cvals, C.int(len(regs)))
|
||||
return errReturn(ucerr)
|
||||
}
|
||||
|
||||
func (u *uc) RegReadBatch(regs []int) ([]uint64, error) {
|
||||
if len(regs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
cregs := make([]C.int, len(regs))
|
||||
for i, v := range regs {
|
||||
cregs[i] = C.int(v)
|
||||
}
|
||||
cregs2 := (*C.int)(unsafe.Pointer(&cregs[0]))
|
||||
vals := make([]uint64, len(regs))
|
||||
cvals := (*C.uint64_t)(unsafe.Pointer(&vals[0]))
|
||||
ucerr := C.uc_reg_read_batch_helper(u.handle, cregs2, cvals, C.int(len(regs)))
|
||||
return vals, errReturn(ucerr)
|
||||
}
|
||||
|
||||
func (u *uc) MemRegions() ([]*MemRegion, error) {
|
||||
var regions *C.struct_uc_mem_region
|
||||
var count C.uint32_t
|
||||
|
Reference in New Issue
Block a user