mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-03 20:35:43 +00:00
add new hook type UC_HOOK_MEM_READ_AFTER, adapted from PR #399 by @farmdve. updated all bindings, except Ruby & Haskell
This commit is contained in:
parent
7e9fe53f19
commit
4083b87032
|
@ -73,6 +73,7 @@ module Common =
|
||||||
let UC_MEM_WRITE_PROT = 22
|
let UC_MEM_WRITE_PROT = 22
|
||||||
let UC_MEM_READ_PROT = 23
|
let UC_MEM_READ_PROT = 23
|
||||||
let UC_MEM_FETCH_PROT = 24
|
let UC_MEM_FETCH_PROT = 24
|
||||||
|
let UC_MEM_READ_AFTER = 25
|
||||||
let UC_HOOK_INTR = 1
|
let UC_HOOK_INTR = 1
|
||||||
let UC_HOOK_INSN = 2
|
let UC_HOOK_INSN = 2
|
||||||
let UC_HOOK_CODE = 4
|
let UC_HOOK_CODE = 4
|
||||||
|
@ -86,6 +87,7 @@ module Common =
|
||||||
let UC_HOOK_MEM_READ = 1024
|
let UC_HOOK_MEM_READ = 1024
|
||||||
let UC_HOOK_MEM_WRITE = 2048
|
let UC_HOOK_MEM_WRITE = 2048
|
||||||
let UC_HOOK_MEM_FETCH = 4096
|
let UC_HOOK_MEM_FETCH = 4096
|
||||||
|
let UC_HOOK_MEM_READ_AFTER = 8192
|
||||||
let UC_HOOK_MEM_UNMAPPED = 112
|
let UC_HOOK_MEM_UNMAPPED = 112
|
||||||
let UC_HOOK_MEM_PROT = 896
|
let UC_HOOK_MEM_PROT = 896
|
||||||
let UC_HOOK_MEM_READ_INVALID = 144
|
let UC_HOOK_MEM_READ_INVALID = 144
|
||||||
|
|
|
@ -68,6 +68,7 @@ const (
|
||||||
MEM_WRITE_PROT = 22
|
MEM_WRITE_PROT = 22
|
||||||
MEM_READ_PROT = 23
|
MEM_READ_PROT = 23
|
||||||
MEM_FETCH_PROT = 24
|
MEM_FETCH_PROT = 24
|
||||||
|
MEM_READ_AFTER = 25
|
||||||
HOOK_INTR = 1
|
HOOK_INTR = 1
|
||||||
HOOK_INSN = 2
|
HOOK_INSN = 2
|
||||||
HOOK_CODE = 4
|
HOOK_CODE = 4
|
||||||
|
@ -81,6 +82,7 @@ const (
|
||||||
HOOK_MEM_READ = 1024
|
HOOK_MEM_READ = 1024
|
||||||
HOOK_MEM_WRITE = 2048
|
HOOK_MEM_WRITE = 2048
|
||||||
HOOK_MEM_FETCH = 4096
|
HOOK_MEM_FETCH = 4096
|
||||||
|
HOOK_MEM_READ_AFTER = 8192
|
||||||
HOOK_MEM_UNMAPPED = 112
|
HOOK_MEM_UNMAPPED = 112
|
||||||
HOOK_MEM_PROT = 896
|
HOOK_MEM_PROT = 896
|
||||||
HOOK_MEM_READ_INVALID = 144
|
HOOK_MEM_READ_INVALID = 144
|
||||||
|
|
|
@ -70,6 +70,7 @@ public interface UnicornConst {
|
||||||
public static final int UC_MEM_WRITE_PROT = 22;
|
public static final int UC_MEM_WRITE_PROT = 22;
|
||||||
public static final int UC_MEM_READ_PROT = 23;
|
public static final int UC_MEM_READ_PROT = 23;
|
||||||
public static final int UC_MEM_FETCH_PROT = 24;
|
public static final int UC_MEM_FETCH_PROT = 24;
|
||||||
|
public static final int UC_MEM_READ_AFTER = 25;
|
||||||
public static final int UC_HOOK_INTR = 1;
|
public static final int UC_HOOK_INTR = 1;
|
||||||
public static final int UC_HOOK_INSN = 2;
|
public static final int UC_HOOK_INSN = 2;
|
||||||
public static final int UC_HOOK_CODE = 4;
|
public static final int UC_HOOK_CODE = 4;
|
||||||
|
@ -83,6 +84,7 @@ public interface UnicornConst {
|
||||||
public static final int UC_HOOK_MEM_READ = 1024;
|
public static final int UC_HOOK_MEM_READ = 1024;
|
||||||
public static final int UC_HOOK_MEM_WRITE = 2048;
|
public static final int UC_HOOK_MEM_WRITE = 2048;
|
||||||
public static final int UC_HOOK_MEM_FETCH = 4096;
|
public static final int UC_HOOK_MEM_FETCH = 4096;
|
||||||
|
public static final int UC_HOOK_MEM_READ_AFTER = 8192;
|
||||||
public static final int UC_HOOK_MEM_UNMAPPED = 112;
|
public static final int UC_HOOK_MEM_UNMAPPED = 112;
|
||||||
public static final int UC_HOOK_MEM_PROT = 896;
|
public static final int UC_HOOK_MEM_PROT = 896;
|
||||||
public static final int UC_HOOK_MEM_READ_INVALID = 144;
|
public static final int UC_HOOK_MEM_READ_INVALID = 144;
|
||||||
|
|
|
@ -66,6 +66,7 @@ UC_MEM_FETCH_UNMAPPED = 21
|
||||||
UC_MEM_WRITE_PROT = 22
|
UC_MEM_WRITE_PROT = 22
|
||||||
UC_MEM_READ_PROT = 23
|
UC_MEM_READ_PROT = 23
|
||||||
UC_MEM_FETCH_PROT = 24
|
UC_MEM_FETCH_PROT = 24
|
||||||
|
UC_MEM_READ_AFTER = 25
|
||||||
UC_HOOK_INTR = 1
|
UC_HOOK_INTR = 1
|
||||||
UC_HOOK_INSN = 2
|
UC_HOOK_INSN = 2
|
||||||
UC_HOOK_CODE = 4
|
UC_HOOK_CODE = 4
|
||||||
|
@ -79,6 +80,7 @@ UC_HOOK_MEM_FETCH_PROT = 512
|
||||||
UC_HOOK_MEM_READ = 1024
|
UC_HOOK_MEM_READ = 1024
|
||||||
UC_HOOK_MEM_WRITE = 2048
|
UC_HOOK_MEM_WRITE = 2048
|
||||||
UC_HOOK_MEM_FETCH = 4096
|
UC_HOOK_MEM_FETCH = 4096
|
||||||
|
UC_HOOK_MEM_READ_AFTER = 8192
|
||||||
UC_HOOK_MEM_UNMAPPED = 112
|
UC_HOOK_MEM_UNMAPPED = 112
|
||||||
UC_HOOK_MEM_PROT = 896
|
UC_HOOK_MEM_PROT = 896
|
||||||
UC_HOOK_MEM_READ_INVALID = 144
|
UC_HOOK_MEM_READ_INVALID = 144
|
||||||
|
|
|
@ -105,6 +105,7 @@ enum uc_hook_idx {
|
||||||
UC_HOOK_MEM_READ_IDX,
|
UC_HOOK_MEM_READ_IDX,
|
||||||
UC_HOOK_MEM_WRITE_IDX,
|
UC_HOOK_MEM_WRITE_IDX,
|
||||||
UC_HOOK_MEM_FETCH_IDX,
|
UC_HOOK_MEM_FETCH_IDX,
|
||||||
|
UC_HOOK_MEM_READ_AFTER_IDX,
|
||||||
|
|
||||||
UC_HOOK_MAX,
|
UC_HOOK_MAX,
|
||||||
};
|
};
|
||||||
|
|
|
@ -195,38 +195,55 @@ typedef enum uc_mem_type {
|
||||||
UC_MEM_WRITE_PROT, // Write to write protected, but mapped, memory
|
UC_MEM_WRITE_PROT, // Write to write protected, but mapped, memory
|
||||||
UC_MEM_READ_PROT, // Read from read protected, but mapped, memory
|
UC_MEM_READ_PROT, // Read from read protected, but mapped, memory
|
||||||
UC_MEM_FETCH_PROT, // Fetch from non-executable, but mapped, memory
|
UC_MEM_FETCH_PROT, // Fetch from non-executable, but mapped, memory
|
||||||
|
UC_MEM_READ_AFTER, // Memory is read from (successful access)
|
||||||
} uc_mem_type;
|
} uc_mem_type;
|
||||||
|
|
||||||
// All type of hooks for uc_hook_add() API.
|
// All type of hooks for uc_hook_add() API.
|
||||||
typedef enum uc_hook_type {
|
typedef enum uc_hook_type {
|
||||||
UC_HOOK_INTR = 1 << 0, // Hook all interrupt/syscall events
|
// Hook all interrupt/syscall events
|
||||||
UC_HOOK_INSN = 1 << 1, // Hook a particular instruction
|
UC_HOOK_INTR = 1 << 0,
|
||||||
UC_HOOK_CODE = 1 << 2, // Hook a range of code
|
// Hook a particular instruction
|
||||||
UC_HOOK_BLOCK = 1 << 3, // Hook basic blocks
|
UC_HOOK_INSN = 1 << 1,
|
||||||
UC_HOOK_MEM_READ_UNMAPPED = 1 << 4, // Hook for memory read on unmapped memory
|
// Hook a range of code
|
||||||
UC_HOOK_MEM_WRITE_UNMAPPED = 1 << 5, // Hook for invalid memory write events
|
UC_HOOK_CODE = 1 << 2,
|
||||||
UC_HOOK_MEM_FETCH_UNMAPPED = 1 << 6, // Hook for invalid memory fetch for execution events
|
// Hook basic blocks
|
||||||
UC_HOOK_MEM_READ_PROT = 1 << 7, // Hook for memory read on read-protected memory
|
UC_HOOK_BLOCK = 1 << 3,
|
||||||
UC_HOOK_MEM_WRITE_PROT = 1 << 8, // Hook for memory write on write-protected memory
|
// Hook for memory read on unmapped memory
|
||||||
UC_HOOK_MEM_FETCH_PROT = 1 << 9, // Hook for memory fetch on non-executable memory
|
UC_HOOK_MEM_READ_UNMAPPED = 1 << 4,
|
||||||
UC_HOOK_MEM_READ = 1 << 10, // Hook memory read events.
|
// Hook for invalid memory write events
|
||||||
UC_HOOK_MEM_WRITE = 1 << 11, // Hook memory write events.
|
UC_HOOK_MEM_WRITE_UNMAPPED = 1 << 5,
|
||||||
UC_HOOK_MEM_FETCH = 1 << 12, // Hook memory fetch for execution events
|
// Hook for invalid memory fetch for execution events
|
||||||
|
UC_HOOK_MEM_FETCH_UNMAPPED = 1 << 6,
|
||||||
|
// Hook for memory read on read-protected memory
|
||||||
|
UC_HOOK_MEM_READ_PROT = 1 << 7,
|
||||||
|
// Hook for memory write on write-protected memory
|
||||||
|
UC_HOOK_MEM_WRITE_PROT = 1 << 8,
|
||||||
|
// Hook for memory fetch on non-executable memory
|
||||||
|
UC_HOOK_MEM_FETCH_PROT = 1 << 9,
|
||||||
|
// Hook memory read events.
|
||||||
|
UC_HOOK_MEM_READ = 1 << 10,
|
||||||
|
// Hook memory write events.
|
||||||
|
UC_HOOK_MEM_WRITE = 1 << 11,
|
||||||
|
// Hook memory fetch for execution events
|
||||||
|
UC_HOOK_MEM_FETCH = 1 << 12,
|
||||||
|
// Hook memory read events, but only successful access.
|
||||||
|
// The callback will be triggered after successful read.
|
||||||
|
UC_HOOK_MEM_READ_AFTER = 1 << 13,
|
||||||
} uc_hook_type;
|
} uc_hook_type;
|
||||||
|
|
||||||
// hook type for all events of unmapped memory access
|
// Hook type for all events of unmapped memory access
|
||||||
#define UC_HOOK_MEM_UNMAPPED (UC_HOOK_MEM_READ_UNMAPPED + UC_HOOK_MEM_WRITE_UNMAPPED + UC_HOOK_MEM_FETCH_UNMAPPED)
|
#define UC_HOOK_MEM_UNMAPPED (UC_HOOK_MEM_READ_UNMAPPED + UC_HOOK_MEM_WRITE_UNMAPPED + UC_HOOK_MEM_FETCH_UNMAPPED)
|
||||||
// hook type for all events of illegal protected memory access
|
// Hook type for all events of illegal protected memory access
|
||||||
#define UC_HOOK_MEM_PROT (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_FETCH_PROT)
|
#define UC_HOOK_MEM_PROT (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_FETCH_PROT)
|
||||||
// hook type for all events of illegal read memory access
|
// Hook type for all events of illegal read memory access
|
||||||
#define UC_HOOK_MEM_READ_INVALID (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_READ_UNMAPPED)
|
#define UC_HOOK_MEM_READ_INVALID (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_READ_UNMAPPED)
|
||||||
// hook type for all events of illegal write memory access
|
// Hook type for all events of illegal write memory access
|
||||||
#define UC_HOOK_MEM_WRITE_INVALID (UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_WRITE_UNMAPPED)
|
#define UC_HOOK_MEM_WRITE_INVALID (UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_WRITE_UNMAPPED)
|
||||||
// hook type for all events of illegal fetch memory access
|
// Hook type for all events of illegal fetch memory access
|
||||||
#define UC_HOOK_MEM_FETCH_INVALID (UC_HOOK_MEM_FETCH_PROT + UC_HOOK_MEM_FETCH_UNMAPPED)
|
#define UC_HOOK_MEM_FETCH_INVALID (UC_HOOK_MEM_FETCH_PROT + UC_HOOK_MEM_FETCH_UNMAPPED)
|
||||||
// hook type for all events of illegal memory access
|
// Hook type for all events of illegal memory access
|
||||||
#define UC_HOOK_MEM_INVALID (UC_HOOK_MEM_UNMAPPED + UC_HOOK_MEM_PROT)
|
#define UC_HOOK_MEM_INVALID (UC_HOOK_MEM_UNMAPPED + UC_HOOK_MEM_PROT)
|
||||||
// hook type for all events of valid memory access
|
// Hook type for all events of valid memory access
|
||||||
#define UC_HOOK_MEM_VALID (UC_HOOK_MEM_READ + UC_HOOK_MEM_WRITE + UC_HOOK_MEM_FETCH)
|
#define UC_HOOK_MEM_VALID (UC_HOOK_MEM_READ + UC_HOOK_MEM_WRITE + UC_HOOK_MEM_FETCH)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -240,6 +240,10 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Unicorn: callback on memory read
|
// Unicorn: callback on memory read
|
||||||
|
// NOTE: this happens before the actual read, so we cannot tell
|
||||||
|
// the callback if read access is succesful, or not.
|
||||||
|
// See UC_HOOK_MEM_READ_AFTER & UC_MEM_READ_AFTER if you only care
|
||||||
|
// about successful read
|
||||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
||||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ) {
|
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ) {
|
||||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||||
|
@ -317,7 +321,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
byte ordering. We should push the LE/BE request down into io. */
|
byte ordering. We should push the LE/BE request down into io. */
|
||||||
res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
|
res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
|
||||||
res = TGT_LE(res);
|
res = TGT_LE(res);
|
||||||
return res;
|
goto _out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle slow unaligned access (it spans two pages or IO). */
|
/* Handle slow unaligned access (it spans two pages or IO). */
|
||||||
|
@ -350,7 +354,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
|
|
||||||
/* Little-endian combine. */
|
/* Little-endian combine. */
|
||||||
res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
|
res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
|
||||||
return res;
|
goto _out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle aligned access or unaligned access in the same page. */
|
/* Handle aligned access or unaligned access in the same page. */
|
||||||
|
@ -375,6 +379,17 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
#else
|
#else
|
||||||
res = glue(glue(ld, LSUFFIX), _le_p)((uint8_t *)haddr);
|
res = glue(glue(ld, LSUFFIX), _le_p)((uint8_t *)haddr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_out:
|
||||||
|
// Unicorn: callback on successful read
|
||||||
|
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
||||||
|
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ_AFTER) {
|
||||||
|
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||||
|
continue;
|
||||||
|
((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ_AFTER, addr, DATA_SIZE, res, hook->user_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,6 +467,10 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Unicorn: callback on memory read
|
// Unicorn: callback on memory read
|
||||||
|
// NOTE: this happens before the actual read, so we cannot tell
|
||||||
|
// the callback if read access is succesful, or not.
|
||||||
|
// See UC_HOOK_MEM_READ_AFTER & UC_MEM_READ_AFTER if you only care
|
||||||
|
// about successful read
|
||||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
||||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ) {
|
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ) {
|
||||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||||
|
@ -528,7 +547,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
byte ordering. We should push the LE/BE request down into io. */
|
byte ordering. We should push the LE/BE request down into io. */
|
||||||
res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
|
res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
|
||||||
res = TGT_BE(res);
|
res = TGT_BE(res);
|
||||||
return res;
|
goto _out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle slow unaligned access (it spans two pages or IO). */
|
/* Handle slow unaligned access (it spans two pages or IO). */
|
||||||
|
@ -561,7 +580,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
|
|
||||||
/* Big-endian combine. */
|
/* Big-endian combine. */
|
||||||
res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
|
res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
|
||||||
return res;
|
goto _out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle aligned access or unaligned access in the same page. */
|
/* Handle aligned access or unaligned access in the same page. */
|
||||||
|
@ -582,6 +601,17 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
|
|
||||||
haddr = addr + env->tlb_table[mmu_idx][index].addend;
|
haddr = addr + env->tlb_table[mmu_idx][index].addend;
|
||||||
res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr);
|
res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr);
|
||||||
|
|
||||||
|
_out:
|
||||||
|
// Unicorn: callback on successful read
|
||||||
|
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
||||||
|
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ_AFTER) {
|
||||||
|
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||||
|
continue;
|
||||||
|
((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ_AFTER, addr, DATA_SIZE, res, hook->user_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif /* DATA_SIZE > 1 */
|
#endif /* DATA_SIZE > 1 */
|
||||||
|
|
Loading…
Reference in a new issue