DR_EXPORT
bool
drmgr_register_bb_instrumentation_ex_event(
/
/
用于在初次回调时设置user data供后续回调使用
drmgr_app2app_ex_cb_t app2app_func,
/
/
用于进入回调时获取所有instrlist_t触发设置user data
drmgr_ilist_ex_cb_t analysis_func,
/
/
处理每个回调,可以获取调最后一个instr
drmgr_insertion_cb_t insertion_func,
/
/
用于最后过滤回调
drmgr_ilist_ex_cb_t instru2instru_func,
/
/
选项参数用于排序所注册的回调执行的顺序和优先级
drmgr_priority_t
*
priority)
{
...
if
(app2app_func !
=
NULL) {
ok
=
drmgr_bb_cb_add(&cblist_app2app, NULL, NULL, NULL, app2app_func, NULL,
NULL, NULL, priority, NULL
/
*
no user data
*
/
) &&
}
if
(analysis_func !
=
NULL) {
ok
=
drmgr_bb_cb_add(&cblist_instrumentation, NULL, NULL, insertion_func,
NULL, analysis_func, NULL, NULL, priority, NULL
/
*
no user data
*
/
) &&
}
if
(instru2instru_func !
=
NULL) {
ok
=
drmgr_bb_cb_add(&cblist_instru2instru, NULL, NULL, NULL, NULL, NULL,
instru2instru_func, NULL, priority, NULL
/
*
no user data
*
/
) &&
}
...
}
/
/
最终由bb_callbacks触发
static
bool
drmgr_bb_cb_add(cb_list_t
*
list
, drmgr_xform_cb_t xform_func,
drmgr_analysis_cb_t analysis_func,
drmgr_insertion_cb_t insertion_func,
/
*
for
quartet (also uses insertion_func)
*
/
drmgr_app2app_ex_cb_t app2app_ex_func,
drmgr_ilist_ex_cb_t analysis_ex_func,
drmgr_ilist_ex_cb_t instru2instru_ex_func,
drmgr_opcode_insertion_cb_t opcode_instrum_fuc,
drmgr_priority_t
*
priority, void
*
user_data
/
*
passed at registration
*
/
)
{
...
dr_register_bb_event(drmgr_bb_event);
...
}
void dr_register_bb_event(dr_emit_flags_t (
*
func)(void
*
drcontext, void
*
tag,
instrlist_t
*
bb,
bool
for_trace,
bool
translating))
{
/
/
client_process_bb处理的就是这个回调数组
add_callback(&bb_callbacks, (void (
*
)(void))func, true);
}
static dr_emit_flags_t
drmgr_bb_event(void
*
drcontext, void
*
tag, instrlist_t
*
bb,
bool
for_trace,
bool
translating)
res
=
drmgr_bb_event_do_instrum_phases(drcontext, tag, bb, for_trace,
translating, pt, &local_info, pair_data, quartet_data);
}
static dr_emit_flags_t
drmgr_bb_event_do_instrum_phases(void
*
drcontext, void
*
tag, instrlist_t
*
bb,
bool
for_trace,
bool
translating, per_thread_t
*
pt,
local_cb_info_t
*
local_info, void
*
*
pair_data,
void
*
*
quartet_data)
{
...
/
/
先处理app2app_func.
for
(quartet_idx
=
0
, i
=
0
; i < local_info
-
>iter_app2app.num_def; i
+
+
) {
e
=
&local_info
-
>iter_app2app.cbs.bb[i];
if
(e
-
>has_quartet) {
res |
=
(
*
e
-
>cb.app2app_ex_cb)(drcontext, tag, bb, for_trace,
translating, &quartet_data[quartet_idx]);
}
else
res |
=
(
*
e
-
>cb.xform_cb)(drcontext, tag, bb, for_trace, translating);
}
/
/
再处理analysis_func
for
(quartet_idx
=
0
, pair_idx
=
0
, i
=
0
; i <
local_info
-
>iter_insert.num_def; i
+
+
) {
e
=
&local_info
-
>iter_insert.cbs.bb[i];
if
(e
-
>has_quartet) {
res |
=
(
*
e
-
>cb.pair_ex.analysis_ex_cb)(
drcontext, tag, bb, for_trace, translating,
quartet_data[quartet_idx]);
}
else
{
if
(e
-
>cb.pair.analysis_cb
=
=
NULL) {
pair_data[pair_idx]
=
NULL;
}
else
{
res |
=
(
*
e
-
>cb.pair.analysis_cb)(drcontext, tag, bb, for_trace,
translating, &pair_data[pair_idx]);
}
/
/
这里面调用了drmgr_bb_event_do_insertion_per_instr里面处理insertion_func
if
(e
-
>is_opcode_insertion) {
res |
=
(
*
e
-
>cb.opcode_insertion_cb)(drcontext, tag, bb, inst, for_trace,
translating, e
-
>registration_user_data);
}
else
if
(e
-
>has_quartet) {
res |
=
(
*
e
-
>cb.pair_ex.insertion_ex_cb)(drcontext, tag, bb, inst,
for_trace,translating, quartet_data[quartet_idx]);
}
else
{
if
(e
-
>cb.pair.insertion_cb !
=
NULL) {
res |
=
(
*
e
-
>cb.pair.insertion_cb)(drcontext, tag, bb, inst,
for_trace, translating, pair_data[pair_idx]);
}
/
/
最后才是instru2instru_func
for
(quartet_idx
=
0
, i
=
0
; i < local_info
-
>iter_instru.num_def; i
+
+
) {
e
=
&local_info
-
>iter_instru.cbs.bb[i];
if
(e
-
>has_quartet) {
res |
=
(
*
e
-
>cb.instru2instru_ex_cb)(drcontext, tag, bb, for_trace,
translating, quartet_data[quartet_idx]);
}
else
res |
=
(
*
e
-
>cb.xform_cb)(drcontext, tag, bb, for_trace, translating);
}
...