mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-22 14:15:32 +00:00
callback to count number of instructions in uc_emu_start() should be executed first. fix #727
This commit is contained in:
parent
8f2d6cd70f
commit
fe466d003a
|
@ -12,9 +12,19 @@ struct list {
|
||||||
struct list_item *head, *tail;
|
struct list_item *head, *tail;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// create a new list
|
||||||
struct list *list_new(void);
|
struct list *list_new(void);
|
||||||
|
|
||||||
|
// removed linked list nodes but does not free their content
|
||||||
void list_clear(struct list *list);
|
void list_clear(struct list *list);
|
||||||
|
|
||||||
|
// insert a new item at the begin of the list.
|
||||||
|
void *list_insert(struct list *list, void *data);
|
||||||
|
|
||||||
|
// append a new item at the end of the list.
|
||||||
void *list_append(struct list *list, void *data);
|
void *list_append(struct list *list, void *data);
|
||||||
|
|
||||||
|
// returns true if entry was removed, false otherwise
|
||||||
bool list_remove(struct list *list, void *data);
|
bool list_remove(struct list *list, void *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -244,6 +244,7 @@ struct uc_struct {
|
||||||
uint32_t target_page_size;
|
uint32_t target_page_size;
|
||||||
uint32_t target_page_align;
|
uint32_t target_page_align;
|
||||||
uint64_t next_pc; // save next PC for some special cases
|
uint64_t next_pc; // save next PC for some special cases
|
||||||
|
bool hook_insert; // insert new hook at begin of the hook list (append by default)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Metadata stub for the variable-size cpu context used with uc_context_*()
|
// Metadata stub for the variable-size cpu context used with uc_context_*()
|
||||||
|
|
22
list.c
22
list.c
|
@ -22,6 +22,28 @@ void list_clear(struct list *list)
|
||||||
list->tail = NULL;
|
list->tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// insert a new item at the begin of the list.
|
||||||
|
// returns generated linked list node, or NULL on failure
|
||||||
|
void *list_insert(struct list *list, void *data)
|
||||||
|
{
|
||||||
|
struct list_item *item = malloc(sizeof(struct list_item));
|
||||||
|
if (item == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
item->data = data;
|
||||||
|
item->next = list->head;
|
||||||
|
|
||||||
|
if (list->tail == NULL) {
|
||||||
|
list->tail = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->head = item;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// append a new item at the end of the list.
|
||||||
// returns generated linked list node, or NULL on failure
|
// returns generated linked list node, or NULL on failure
|
||||||
void *list_append(struct list *list, void *data)
|
void *list_append(struct list *list, void *data)
|
||||||
{
|
{
|
||||||
|
|
36
uc.c
36
uc.c
|
@ -594,7 +594,13 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time
|
||||||
}
|
}
|
||||||
// set up count hook to count instructions.
|
// set up count hook to count instructions.
|
||||||
if (count > 0 && uc->count_hook == 0) {
|
if (count > 0 && uc->count_hook == 0) {
|
||||||
|
// callback to count instructions must be run before everything else,
|
||||||
|
// so instead of appending, we must insert the hook at the begin
|
||||||
|
// of the hook list
|
||||||
|
uc->hook_insert = 1;
|
||||||
uc_err err = uc_hook_add(uc, &uc->count_hook, UC_HOOK_CODE, hook_count_cb, NULL, 1, 0);
|
uc_err err = uc_hook_add(uc, &uc->count_hook, UC_HOOK_CODE, hook_count_cb, NULL, 1, 0);
|
||||||
|
// restore to append mode for uc_hook_add()
|
||||||
|
uc->hook_insert = 0;
|
||||||
if (err != UC_ERR_OK) {
|
if (err != UC_ERR_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1043,9 +1049,16 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list_append(&uc->hook[UC_HOOK_INSN_IDX], hook) == NULL) {
|
if (uc->hook_insert) {
|
||||||
free(hook);
|
if (list_insert(&uc->hook[UC_HOOK_INSN_IDX], hook) == NULL) {
|
||||||
return UC_ERR_NOMEM;
|
free(hook);
|
||||||
|
return UC_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (list_append(&uc->hook[UC_HOOK_INSN_IDX], hook) == NULL) {
|
||||||
|
free(hook);
|
||||||
|
return UC_ERR_NOMEM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hook->refs++;
|
hook->refs++;
|
||||||
|
@ -1056,11 +1069,20 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
|
||||||
if ((type >> i) & 1) {
|
if ((type >> i) & 1) {
|
||||||
// TODO: invalid hook error?
|
// TODO: invalid hook error?
|
||||||
if (i < UC_HOOK_MAX) {
|
if (i < UC_HOOK_MAX) {
|
||||||
if (list_append(&uc->hook[i], hook) == NULL) {
|
if (uc->hook_insert) {
|
||||||
if (hook->refs == 0) {
|
if (list_insert(&uc->hook[i], hook) == NULL) {
|
||||||
free(hook);
|
if (hook->refs == 0) {
|
||||||
|
free(hook);
|
||||||
|
}
|
||||||
|
return UC_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (list_append(&uc->hook[i], hook) == NULL) {
|
||||||
|
if (hook->refs == 0) {
|
||||||
|
free(hook);
|
||||||
|
}
|
||||||
|
return UC_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
return UC_ERR_NOMEM;
|
|
||||||
}
|
}
|
||||||
hook->refs++;
|
hook->refs++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue