mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-25 07:15:19 +00:00
Fix zero interrupt issue ##esil
This commit is contained in:
parent
0a7690933c
commit
57c9ab3da6
@ -11,28 +11,41 @@ static void _interrupt_free_cb(void *user) {
|
||||
free (intr);
|
||||
}
|
||||
|
||||
R_API void r_anal_esil_interrupts_init(RAnalEsil *esil) {
|
||||
if (!esil) {
|
||||
return;
|
||||
static bool _set_interrupt(RAnalEsil *esil, RAnalEsilInterrupt *intr) {
|
||||
return intr->handler->num ?
|
||||
dict_set (esil->interrupts, intr->handler->num, intr->handler->num, intr) :
|
||||
(esil->intr0 = intr, true);
|
||||
}
|
||||
|
||||
static RAnalEsilInterrupt *_get_interrupt(RAnalEsil *esil, ut32 intr_num) {
|
||||
return intr_num ?
|
||||
(RAnalEsilInterrupt *)dict_getu(esil->interrupts, intr_num) :
|
||||
esil->intr0;
|
||||
}
|
||||
|
||||
static void _del_interrupt(RAnalEsil *esil, ut32 intr_num) {
|
||||
if (intr_num) {
|
||||
dict_del (esil->interrupts, intr_num);
|
||||
} else {
|
||||
esil->intr0 = NULL;
|
||||
}
|
||||
esil->interrupts = dict_new (sizeof(ut32), NULL);
|
||||
}
|
||||
|
||||
R_API void r_anal_esil_interrupts_init(RAnalEsil *esil) {
|
||||
r_return_if_fail (esil);
|
||||
esil->interrupts = dict_new (sizeof (ut32), NULL);
|
||||
esil->intr0 = NULL; // is this needed?
|
||||
}
|
||||
|
||||
R_API RAnalEsilInterrupt *r_anal_esil_interrupt_new(RAnalEsil *esil, ut32 src_id, RAnalEsilInterruptHandler *ih) {
|
||||
RAnalEsilInterrupt *intr;
|
||||
|
||||
if (!esil || !ih || !ih->cb) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
intr = R_NEW0(RAnalEsilInterrupt);
|
||||
r_return_val_if_fail (esil && ih && ih->cb, NULL);
|
||||
RAnalEsilInterrupt *intr = R_NEW0 (RAnalEsilInterrupt);
|
||||
if (!intr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
intr->handler = ih;
|
||||
if (ih->init && ih->fini) {
|
||||
intr->user = ih->init(esil);
|
||||
intr->user = ih->init (esil);
|
||||
}
|
||||
intr->src_id = src_id;
|
||||
r_anal_esil_claim_source (esil, src_id);
|
||||
@ -41,38 +54,30 @@ R_API RAnalEsilInterrupt *r_anal_esil_interrupt_new(RAnalEsil *esil, ut32 src_id
|
||||
|
||||
R_API void r_anal_esil_interrupt_free(RAnalEsil *esil, RAnalEsilInterrupt *intr) {
|
||||
if (intr && esil) {
|
||||
dict_del (esil->interrupts, intr->handler->num);
|
||||
_del_interrupt (esil, intr->handler->num);
|
||||
}
|
||||
if (intr) {
|
||||
if (intr->user) {
|
||||
intr->handler->fini(intr->user); //fini must exist when user is !NULL
|
||||
intr->handler->fini (intr->user); //fini must exist when user is !NULL
|
||||
}
|
||||
r_anal_esil_release_source (esil, intr->src_id);
|
||||
}
|
||||
free(intr);
|
||||
free (intr);
|
||||
}
|
||||
|
||||
R_API bool r_anal_esil_set_interrupt(RAnalEsil *esil, RAnalEsilInterrupt *intr) {
|
||||
RAnalEsilInterrupt *o_intr;
|
||||
|
||||
if (!esil || !esil->interrupts || !intr || !intr->handler || !intr->handler->cb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if interrupt is already set
|
||||
o_intr = (RAnalEsilInterrupt *)dict_getu(esil->interrupts, intr->handler->num);
|
||||
r_return_val_if_fail (esil && esil->interrupts && intr && intr->handler && intr->handler->cb, false);
|
||||
// check if interrupt is already set
|
||||
RAnalEsilInterrupt *o_intr = _get_interrupt(esil, intr->handler->num);
|
||||
if (o_intr) {
|
||||
r_anal_esil_interrupt_free(esil, o_intr);
|
||||
r_anal_esil_interrupt_free (esil, o_intr);
|
||||
}
|
||||
|
||||
//set the new interrupt
|
||||
return dict_set(esil->interrupts, intr->handler->num, intr->handler->num, intr);
|
||||
//set the new interrupt
|
||||
return _set_interrupt(esil, intr);
|
||||
}
|
||||
|
||||
R_API int r_anal_esil_fire_interrupt(RAnalEsil *esil, ut32 intr_num) {
|
||||
if (!esil) {
|
||||
return false;
|
||||
}
|
||||
r_return_val_if_fail (esil, false);
|
||||
|
||||
if (esil->cmd && esil->cmd (esil, esil->cmd_intr, intr_num, 0)) { //compatibility
|
||||
return true;
|
||||
@ -82,7 +87,7 @@ R_API int r_anal_esil_fire_interrupt(RAnalEsil *esil, ut32 intr_num) {
|
||||
eprintf ("no interrupts initialized\n");
|
||||
return false;
|
||||
}
|
||||
RAnalEsilInterrupt *intr = (RAnalEsilInterrupt *)dict_getu(esil->interrupts, intr_num);
|
||||
RAnalEsilInterrupt *intr = _get_interrupt (esil, intr_num);
|
||||
if (!intr) {
|
||||
eprintf ("no handler registered for 0x%x\n", intr_num);
|
||||
}
|
||||
@ -94,22 +99,19 @@ R_API bool r_anal_esil_load_interrupts (RAnalEsil *esil, RAnalEsilInterruptHandl
|
||||
RAnalEsilInterrupt *intr;
|
||||
ut32 i = 0;
|
||||
|
||||
if (!esil || !esil->interrupts || !handlers) {
|
||||
return false;
|
||||
}
|
||||
r_return_val_if_fail (esil && esil->interrupts && handlers, false);
|
||||
|
||||
while (handlers[i]) {
|
||||
intr = (RAnalEsilInterrupt *)dict_getu(esil->interrupts, handlers[i]->num);
|
||||
intr = _get_interrupt (esil, handlers[i]->num);
|
||||
if (intr) {
|
||||
//first free, then load the new handler or stuff might break in the handlers
|
||||
r_anal_esil_interrupt_free (esil, intr);
|
||||
}
|
||||
intr = r_anal_esil_interrupt_new (esil, src_id, handlers[i]);
|
||||
if (intr) {
|
||||
r_anal_esil_set_interrupt (esil, intr);
|
||||
} else {
|
||||
if (!intr) {
|
||||
return false;
|
||||
}
|
||||
r_anal_esil_set_interrupt (esil, intr);
|
||||
i++;
|
||||
}
|
||||
|
||||
@ -117,16 +119,15 @@ R_API bool r_anal_esil_load_interrupts (RAnalEsil *esil, RAnalEsilInterruptHandl
|
||||
}
|
||||
|
||||
R_API bool r_anal_esil_load_interrupts_from_lib(RAnalEsil *esil, const char *path) {
|
||||
RAnalEsilInterruptHandler **handlers;
|
||||
r_return_val_if_fail (esil, false);
|
||||
ut32 src_id = r_anal_esil_load_source (esil, path);
|
||||
|
||||
if (!src_id) {
|
||||
if (!src_id) { // why id=0 is invalid?
|
||||
return false;
|
||||
}
|
||||
|
||||
handlers = (RAnalEsilInterruptHandler **)r_lib_dl_sym (r_anal_esil_get_source (esil, src_id), "interrupts");
|
||||
RAnalEsilInterruptHandler **handlers = (RAnalEsilInterruptHandler **)\
|
||||
r_lib_dl_sym (r_anal_esil_get_source (esil, src_id), "interrupts");
|
||||
if (!handlers) {
|
||||
r_anal_esil_release_source(esil, src_id); //unload
|
||||
r_anal_esil_release_source (esil, src_id); //unload
|
||||
return false;
|
||||
}
|
||||
return r_anal_esil_load_interrupts (esil, handlers, src_id);
|
||||
@ -134,6 +135,8 @@ R_API bool r_anal_esil_load_interrupts_from_lib(RAnalEsil *esil, const char *pat
|
||||
|
||||
R_API void r_anal_esil_interrupts_fini(RAnalEsil *esil) {
|
||||
if (esil && esil->interrupts) {
|
||||
_interrupt_free_cb (esil->intr0);
|
||||
esil->intr0 = NULL;
|
||||
esil->interrupts->f = _interrupt_free_cb;
|
||||
dict_free (esil->interrupts);
|
||||
esil->interrupts = NULL;
|
||||
|
@ -1114,6 +1114,8 @@ typedef struct r_anal_esil_t {
|
||||
Sdb *ops;
|
||||
RIDStorage *sources;
|
||||
SdbMini *interrupts;
|
||||
//this is a disgusting workaround, because we have no ht-like storage without magic keys, that you cannot use, with int-keys
|
||||
RAnalEsilInterrupt *intr0;
|
||||
/* deep esil parsing fills this */
|
||||
Sdb *stats;
|
||||
Sdb *db_trace;
|
||||
|
Loading…
x
Reference in New Issue
Block a user