一、说明
1. include/trace/hooks/vendor_hooks.h 中定义 #define DECLARE_HOOK DECLARE_TRACE。
2. hook模块的实现端(比如binder.c)和vendor使用端(比如要hook binder.c的ko驱动)都是使用端,drivers/android/vendor_hooks.c 才是实现端。
二、使用端展开
1. tmp.c模拟binder.c和使用binder.c导出的hook。
/* 拷贝内核中的配置事先定义好 */ #define CONFIG_MODULES 1 #define CONFIG_TRACEPOINTS 1 #define CONFIG_HAVE_SYSCALL_TRACEPOINTS 1 #define CONFIG_HAVE_ARCH_PREL32_RELOCATIONS 1 #define CONFIG_TRACING 1 #define MODULE 1 //编译成ko才定义 #define CONFIG_ANDROID_VENDOR_HOOKS 1 //vnedor hook特有,必须有,否则解析出来是错的 /* * 在没有define CREATE_TRACE_POINTS 的情况下, * 这三个无论是否define了解析出来是完全一样的。 */ #define CONFIG_PERF_EVENTS 1 #define CONFIG_KPROBE_EVENTS 1 #define CONFIG_UPROBE_EVENTS 1 #define CONFIG_BPF_EVENTS 1 //-------------------------------------------- #include <trace/hooks/binder.h> /* 模拟binder.c */ int main() { trace_android_vh_binder_set_priority(transaction, task); return 0; } //-------------------------------------------- /* 模拟 vendor ko 模块注册hook handler函数 */ void register_binder_hooks(void) register_trace_android_vh_binder_set_priority(android_vh_binder_set_priority_handler, NULL); } //--------------------------------------------
2. 只保留一个hook声明的trace/hooks/binder.h
#undef TRACE_SYSTEM #define TRACE_SYSTEM binder #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH trace/hooks #if !defined(_TRACE_HOOK_BINDER_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_HOOK_BINDER_H #include <linux/tracepoint.h> #include <trace/hooks/vendor_hooks.h> DECLARE_HOOK(android_vh_binder_set_priority, TP_PROTO(struct binder_transaction *t, struct task_struct *task), TP_ARGS(t, task)); #endif /* _TRACE_HOOK_BINDER_H */ /* This part must be outside protection */ #include <trace/define_trace.h>
3. export C_INCLUDE_PATH=. 然后 gcc -E tmp.c 展开
struct static_call_key; struct trace_print_flags { unsigned long mask; const char *name; }; struct trace_print_flags_u64 { unsigned long long mask; const char *name; }; struct tracepoint_func { void *func; void *data; int prio; }; struct tracepoint { const char *name; struct static_key key; struct static_call_key *static_call_key; void *static_call_tramp; void *iterator; int (*regfunc)(void); void (*unregfunc)(void); struct tracepoint_func __rcu *funcs; }; typedef const int tracepoint_ptr_t; struct bpf_raw_event_map { struct tracepoint *tp; void *bpf_func; u32 num_args; u32 writable_size; } __aligned(32); static inline int static_call_init(void) { return 0; } struct static_call_key { void *func; }; static inline void __static_call_nop(void) { } static inline void __static_call_update(struct static_call_key *key, void *tramp, void *func) { WRITE_ONCE(key->func, func); } static inline int static_call_text_reserved(void *start, void *end) { return 0; } struct module; struct tracepoint; struct notifier_block; struct trace_eval_map { const char *system; const char *eval_string; unsigned long eval_value; }; extern struct srcu_struct tracepoint_srcu; extern int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data); extern int tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data, int prio); extern int tracepoint_probe_register_prio_may_exist(struct tracepoint *tp, void *probe, void *data, int prio); extern int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data); static inline int tracepoint_probe_register_may_exist(struct tracepoint *tp, void *probe, void *data) { return tracepoint_probe_register_prio_may_exist(tp, probe, data, 10); } extern void for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv), void *priv); struct tp_module { struct list_head list; struct module *mod; }; bool trace_module_has_bad_taint(struct module *mod); extern int register_tracepoint_module_notifier(struct notifier_block *nb); extern int unregister_tracepoint_module_notifier(struct notifier_block *nb); static inline void tracepoint_synchronize_unregister(void) { synchronize_srcu(&tracepoint_srcu); synchronize_rcu(); } extern int syscall_regfunc(void); extern void syscall_unregfunc(void); static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) { return offset_to_ptr(p); } int android_rvh_probe_register(struct tracepoint *tp, void *probe, void *data); extern int __traceiter_android_vh_binder_set_priority(void *__data, struct binder_transaction *t, struct task_struct *task); DECLARE_STATIC_CALL(tp_func_android_vh_binder_set_priority, __traceiter_android_vh_binder_set_priority); extern struct tracepoint __tracepoint_android_vh_binder_set_priority; static inline void __nocfi trace_android_vh_binder_set_priority(struct binder_transaction *t, struct task_struct *task) { if (static_key_false(&__tracepoint_android_vh_binder_set_priority.key)) do { struct tracepoint_func *it_func_ptr; int __maybe_unused __idx = 0; void *__data; if (!(cpu_online(raw_smp_processor_id()))) return; WARN_ON_ONCE(0 && in_nmi()); preempt_disable_notrace(); if (0) { __idx = srcu_read_lock_notrace(&tracepoint_srcu); rcu_irq_enter_irqson(); } it_func_ptr = rcu_dereference_raw((&__tracepoint_android_vh_binder_set_priority)->funcs); if (it_func_ptr) { __data = (it_func_ptr)->data; __traceiter_android_vh_binder_set_priority(__data, t, task); } if (0) { rcu_irq_exit_irqson(); srcu_read_unlock_notrace(&tracepoint_srcu, __idx); } preempt_enable_notrace(); } while (0); if (IS_ENABLED(CONFIG_LOCKDEP) && (cpu_online(raw_smp_processor_id()))) { rcu_read_lock_sched_notrace(); rcu_dereference_sched(__tracepoint_android_vh_binder_set_priority.funcs); rcu_read_unlock_sched_notrace(); } } static inline int register_trace_android_vh_binder_set_priority(void (*probe)(void *__data, struct binder_transaction *t, struct task_struct *task), void *data) { return tracepoint_probe_register(&__tracepoint_android_vh_binder_set_priority, (void *)probe, data); } static inline int register_trace_prio_android_vh_binder_set_priority(void (*probe)(void *__data, struct binder_transaction *t, struct task_struct *task), void *data, int prio) { return tracepoint_probe_register_prio(&__tracepoint_android_vh_binder_set_priority, (void *)probe, data, prio); } static inline int unregister_trace_android_vh_binder_set_priority(void (*probe)(void *__data, struct binder_transaction *t, struct task_struct *task), void *data) { return tracepoint_probe_unregister(&__tracepoint_android_vh_binder_set_priority, (void *)probe, data); } static inline void check_trace_callback_type_android_vh_binder_set_priority(void (*cb)(void *__data, struct binder_transaction *t, struct task_struct *task)) { } static inline bool trace_android_vh_binder_set_priority_enabled(void) { return static_key_false(&__tracepoint_android_vh_binder_set_priority.key); } int main() { trace_android_vh_binder_set_priority(transaction, task); return 0; } void register_binder_hooks(void) register_trace_android_vh_binder_set_priority(android_vh_binder_set_priority_handler, NULL); }
三、实现端展开
1. 只保留一个并可直接解析的 vendor_hooks.c
/* ------------ system config ------------- */ #define CONFIG_MODULES 1 #define CONFIG_TRACEPOINTS 1 #define CONFIG_HAVE_SYSCALL_TRACEPOINTS 1 #define CONFIG_HAVE_ARCH_PREL32_RELOCATIONS 1 #define CONFIG_TRACING 1 #define MODULE 1 //编译成ko才定义 #define CONFIG_ANDROID_VENDOR_HOOKS 1 //vnedor hook特有,必须有,否则解析出来是错的 /* * 在没有define CREATE_TRACE_POINTS 的情况下, * 这三个无论是否define了解析出来是完全一样的。 */ #define CONFIG_PERF_EVENTS 1 #define CONFIG_KPROBE_EVENTS 1 #define CONFIG_UPROBE_EVENTS 1 #define CONFIG_BPF_EVENTS 1 /* ---------------------------------------- */ #define CREATE_TRACE_POINTS //实现端 #include <trace/hooks/vendor_hooks.h> #include <linux/tracepoint.h> #include <trace/hooks/binder.h> EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_set_priority);
2.gcc -E vendor_hooks.c 展开
struct static_call_key; struct trace_print_flags { unsigned long mask; const char *name; }; struct trace_print_flags_u64 { unsigned long long mask; const char *name; }; struct tracepoint_func { void *func; void *data; int prio; }; struct tracepoint { const char *name; struct static_key key; struct static_call_key *static_call_key; void *static_call_tramp; void *iterator; int (*regfunc)(void); void (*unregfunc)(void); struct tracepoint_func __rcu *funcs; }; typedef const int tracepoint_ptr_t; struct bpf_raw_event_map { struct tracepoint *tp; void *bpf_func; u32 num_args; u32 writable_size; } __aligned(32); static inline int static_call_init(void) { return 0; } struct static_call_key { void *func; }; static inline void __static_call_nop(void) { } static inline void __static_call_update(struct static_call_key *key, void *tramp, void *func) { WRITE_ONCE(key->func, func); } static inline int static_call_text_reserved(void *start, void *end) { return 0; } struct module; struct tracepoint; struct notifier_block; struct trace_eval_map { const char *system; const char *eval_string; unsigned long eval_value; }; extern struct srcu_struct tracepoint_srcu; extern int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data); extern int tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data, int prio); extern int tracepoint_probe_register_prio_may_exist(struct tracepoint *tp, void *probe, void *data, int prio); extern int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data); static inline int tracepoint_probe_register_may_exist(struct tracepoint *tp, void *probe, void *data) { return tracepoint_probe_register_prio_may_exist(tp, probe, data, 10); } extern void for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv), void *priv); struct tp_module { struct list_head list; struct module *mod; }; bool trace_module_has_bad_taint(struct module *mod); extern int register_tracepoint_module_notifier(struct notifier_block *nb); extern int unregister_tracepoint_module_notifier(struct notifier_block *nb); static inline void tracepoint_synchronize_unregister(void) { synchronize_srcu(&tracepoint_srcu); synchronize_rcu(); } extern int syscall_regfunc(void); extern void syscall_unregfunc(void); static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) { return offset_to_ptr(p); } int android_rvh_probe_register(struct tracepoint *tp, void *probe, void *data); int android_rvh_probe_register(struct tracepoint *tp, void *probe, void *data); extern int __traceiter_android_vh_binder_set_priority(void *__data, struct binder_transaction *t, struct task_struct *task); DECLARE_STATIC_CALL(tp_func_android_vh_binder_set_priority, __traceiter_android_vh_binder_set_priority); extern struct tracepoint __tracepoint_android_vh_binder_set_priority; static inline void __nocfi trace_android_vh_binder_set_priority(struct binder_transaction *t, struct task_struct *task) { if (static_key_false(&__tracepoint_android_vh_binder_set_priority.key)) do { struct tracepoint_func *it_func_ptr; int __maybe_unused __idx = 0; void *__data; if (!(cpu_online(raw_smp_processor_id()))) return; WARN_ON_ONCE(0 && in_nmi()); preempt_disable_notrace(); if (0) { __idx = srcu_read_lock_notrace(&tracepoint_srcu); rcu_irq_enter_irqson(); } it_func_ptr = rcu_dereference_raw((&__tracepoint_android_vh_binder_set_priority)->funcs); if (it_func_ptr) { __data = (it_func_ptr)->data; __traceiter_android_vh_binder_set_priority(__data, t, task); } if (0) { rcu_irq_exit_irqson(); srcu_read_unlock_notrace(&tracepoint_srcu, __idx); } preempt_enable_notrace(); } while (0); if (IS_ENABLED(CONFIG_LOCKDEP) && (cpu_online(raw_smp_processor_id()))) { rcu_read_lock_sched_notrace(); rcu_dereference_sched(__tracepoint_android_vh_binder_set_priority.funcs); rcu_read_unlock_sched_notrace(); } } static inline int register_trace_android_vh_binder_set_priority(void (*probe)(void *__data, struct binder_transaction *t, struct task_struct *task), void *data) { return tracepoint_probe_register(&__tracepoint_android_vh_binder_set_priority, (void *)probe, data); } static inline int register_trace_prio_android_vh_binder_set_priority(void (*probe)(void *__data, struct binder_transaction *t, struct task_struct *task), void *data, int prio) { return tracepoint_probe_register_prio(&__tracepoint_android_vh_binder_set_priority, (void *)probe, data, prio); } static inline int unregister_trace_android_vh_binder_set_priority(void (*probe)(void *__data, struct binder_transaction *t, struct task_struct *task), void *data) { return tracepoint_probe_unregister(&__tracepoint_android_vh_binder_set_priority, (void *)probe, data); } static inline void check_trace_callback_type_android_vh_binder_set_priority(void (*cb)(void *__data, struct binder_transaction *t, struct task_struct *task)) { } static inline bool trace_android_vh_binder_set_priority_enabled(void) { return static_key_false(&__tracepoint_android_vh_binder_set_priority.key); } int android_rvh_probe_register(struct tracepoint *tp, void *probe, void *data); static const char __tpstrtab_android_vh_binder_set_priority[] __section("__tracepoints_strings") = "android_vh_binder_set_priority"; extern struct static_call_key STATIC_CALL_KEY(tp_func_android_vh_binder_set_priority); int __traceiter_android_vh_binder_set_priority(void *__data, struct binder_transaction *t, struct task_struct *task); struct tracepoint __tracepoint_android_vh_binder_set_priority __used __section("__tracepoints") = { .name = __tpstrtab_android_vh_binder_set_priority, .key = STATIC_KEY_INIT_FALSE, .static_call_key = &STATIC_CALL_KEY(tp_func_android_vh_binder_set_priority), .static_call_tramp = NULL, .iterator = &__traceiter_android_vh_binder_set_priority, .regfunc = NULL, .unregfunc = NULL, .funcs = NULL }; asm(".section \"__tracepoints_ptrs\", \"a\" \n" ".balign 4 \n" " .long __tracepoint_" "android_vh_binder_set_priority" " - . \n" " .previous \n"); int __nocfi __traceiter_android_vh_binder_set_priority(void *__data, struct binder_transaction *t, struct task_struct *task) { struct tracepoint_func *it_func_ptr; void *it_func; it_func_ptr = rcu_dereference_raw((&__tracepoint_android_vh_binder_set_priority)->funcs); if (it_func_ptr) { do { it_func = (it_func_ptr)->func; __data = (it_func_ptr)->data; ((void(*)(void *, struct binder_transaction *t, struct task_struct *task))(it_func))(__data, t, task); } while ((++it_func_ptr)->func); } return 0; } DECLARE_STATIC_CALL(tp_func_android_vh_binder_set_priority, __traceiter_android_vh_binder_set_priority); struct static_call_key STATIC_CALL_KEY(tp_func_android_vh_binder_set_priority) = { .func = __traceiter_android_vh_binder_set_priority, }; struct trace_array; struct array_buffer; struct tracer; struct dentry; struct bpf_prog; const char *trace_print_flags_seq(struct trace_seq *p, const char *delim, unsigned long flags, const struct trace_print_flags *flag_array); const char *trace_print_symbols_seq(struct trace_seq *p, unsigned long val, const struct trace_print_flags *symbol_array); const char *trace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr, unsigned int bitmask_size); const char *trace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int len, bool concatenate); const char *trace_print_array_seq(struct trace_seq *p, const void *buf, int count, size_t el_size); const char * trace_print_hex_dump_seq(struct trace_seq *p, const char *prefix_str, int prefix_type, int rowsize, int groupsize, const void *buf, size_t len, bool ascii); struct trace_iterator; struct trace_event; int trace_raw_output_prep(struct trace_iterator *iter,struct trace_event *event); struct trace_entry { unsigned short type; unsigned char flags; unsigned char preempt_count; int pid; }; struct trace_iterator { struct trace_array *tr; struct tracer *trace; struct array_buffer *array_buffer; void *private; int cpu_file; struct mutex mutex; struct ring_buffer_iter **buffer_iter; unsigned long iter_flags; void *temp; unsigned int temp_size; struct trace_seq tmp_seq; cpumask_var_t started; bool snapshot; struct trace_seq seq; struct trace_entry *ent; unsigned long lost_events; int leftover; int ent_size; int cpu; u64 ts; loff_t pos; long idx; }; enum trace_iter_flags { TRACE_FILE_LAT_FMT = 1, TRACE_FILE_ANNOTATE = 2, TRACE_FILE_TIME_IN_NS = 4, }; typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, int flags, struct trace_event *event); struct trace_event_functions { trace_print_func trace; trace_print_func raw; trace_print_func hex; trace_print_func binary; }; struct trace_event { struct hlist_node node; struct list_head list; int type; struct trace_event_functions *funcs; }; extern int register_trace_event(struct trace_event *event); extern int unregister_trace_event(struct trace_event *event); enum print_line_t { TRACE_TYPE_PARTIAL_LINE = 0, TRACE_TYPE_HANDLED = 1, TRACE_TYPE_UNHANDLED = 2, TRACE_TYPE_NO_CONSUME = 3 }; enum print_line_t trace_handle_return(struct trace_seq *s); void tracing_generic_entry_update(struct trace_entry *entry, unsigned short type, unsigned long flags, int pc); struct trace_event_file; struct ring_buffer_event * trace_event_buffer_lock_reserve(struct trace_buffer **current_buffer, struct trace_event_file *trace_file, int type, unsigned long len, unsigned long flags, int pc); void tracing_record_taskinfo(struct task_struct *task, int flags); void tracing_record_taskinfo_sched_switch(struct task_struct *prev, struct task_struct *next, int flags); void tracing_record_cmdline(struct task_struct *task); void tracing_record_tgid(struct task_struct *task); int trace_output_call(struct trace_iterator *iter, char *name, char *fmt, ...); struct event_filter; enum trace_reg { TRACE_REG_REGISTER, TRACE_REG_UNREGISTER, TRACE_REG_PERF_REGISTER, TRACE_REG_PERF_UNREGISTER, TRACE_REG_PERF_OPEN, TRACE_REG_PERF_CLOSE, TRACE_REG_PERF_ADD, TRACE_REG_PERF_DEL, }; struct trace_event_call; struct trace_event_fields { const char *type; union { struct { const char *name; const int size; const int align; const int is_signed; const int filter_type; }; int (*define_fields)(struct trace_event_call *); }; }; struct trace_event_class { const char *system; void *probe; void *perf_probe; int (*reg)(struct trace_event_call *event, enum trace_reg type, void *data); struct trace_event_fields *fields_array; struct list_head *(*get_fields)(struct trace_event_call *); struct list_head fields; int (*raw_init)(struct trace_event_call *); }; extern int trace_event_reg(struct trace_event_call *event, enum trace_reg type, void *data); struct trace_event_buffer { struct trace_buffer *buffer; struct ring_buffer_event *event; struct trace_event_file *trace_file; void *entry; unsigned long flags; int pc; struct pt_regs *regs; }; void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer, struct trace_event_file *trace_file, unsigned long len); void trace_event_buffer_commit(struct trace_event_buffer *fbuffer); enum { TRACE_EVENT_FL_FILTERED_BIT, TRACE_EVENT_FL_CAP_ANY_BIT, TRACE_EVENT_FL_NO_SET_FILTER_BIT, TRACE_EVENT_FL_IGNORE_ENABLE_BIT, TRACE_EVENT_FL_TRACEPOINT_BIT, TRACE_EVENT_FL_KPROBE_BIT, TRACE_EVENT_FL_UPROBE_BIT, }; enum { TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT), TRACE_EVENT_FL_TRACEPOINT = (1 << TRACE_EVENT_FL_TRACEPOINT_BIT), TRACE_EVENT_FL_KPROBE = (1 << TRACE_EVENT_FL_KPROBE_BIT), TRACE_EVENT_FL_UPROBE = (1 << TRACE_EVENT_FL_UPROBE_BIT), }; struct trace_event_call { struct list_head list; struct trace_event_class *class; union { char *name; struct tracepoint *tp; }; struct trace_event event; char *print_fmt; struct event_filter *filter; void *mod; void *data; int flags; int perf_refcount; struct hlist_head __percpu *perf_events; struct bpf_prog_array __rcu *prog_array; int (*perf_perm)(struct trace_event_call *, struct perf_event *); }; static inline bool bpf_prog_array_valid(struct trace_event_call *call) { return !!READ_ONCE(call->prog_array); } static inline const char *trace_event_name(struct trace_event_call *call) { if (call->flags & TRACE_EVENT_FL_TRACEPOINT) return call->tp ? call->tp->name : NULL; else return call->name; } static inline struct list_head *trace_get_fields(struct trace_event_call *event_call) { if (!event_call->class->get_fields) return &event_call->class->fields; return event_call->class->get_fields(event_call); } struct trace_array; struct trace_subsystem_dir; enum { EVENT_FILE_FL_ENABLED_BIT, EVENT_FILE_FL_RECORDED_CMD_BIT, EVENT_FILE_FL_RECORDED_TGID_BIT, EVENT_FILE_FL_FILTERED_BIT, EVENT_FILE_FL_NO_SET_FILTER_BIT, EVENT_FILE_FL_SOFT_MODE_BIT, EVENT_FILE_FL_SOFT_DISABLED_BIT, EVENT_FILE_FL_TRIGGER_MODE_BIT, EVENT_FILE_FL_TRIGGER_COND_BIT, EVENT_FILE_FL_PID_FILTER_BIT, EVENT_FILE_FL_WAS_ENABLED_BIT, }; extern struct trace_event_file *trace_get_event_file(const char *instance, const char *system, const char *event); extern void trace_put_event_file(struct trace_event_file *file); enum dynevent_type { DYNEVENT_TYPE_SYNTH = 1, DYNEVENT_TYPE_KPROBE, DYNEVENT_TYPE_NONE, }; struct dynevent_cmd; typedef int (*dynevent_create_fn_t)(struct dynevent_cmd *cmd); struct dynevent_cmd { struct seq_buf seq; const char *event_name; unsigned int n_fields; enum dynevent_type type; dynevent_create_fn_t run_command; void *private_data; }; extern int dynevent_create(struct dynevent_cmd *cmd); extern int synth_event_delete(const char *name); extern void synth_event_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen); extern int __synth_event_gen_cmd_start(struct dynevent_cmd *cmd, const char *name, struct module *mod, ...); struct synth_field_desc { const char *type; const char *name; }; extern int synth_event_gen_cmd_array_start(struct dynevent_cmd *cmd, const char *name, struct module *mod, struct synth_field_desc *fields, unsigned int n_fields); extern int synth_event_create(const char *name, struct synth_field_desc *fields, unsigned int n_fields, struct module *mod); extern int synth_event_add_field(struct dynevent_cmd *cmd, const char *type, const char *name); extern int synth_event_add_field_str(struct dynevent_cmd *cmd, const char *type_name); extern int synth_event_add_fields(struct dynevent_cmd *cmd, struct synth_field_desc *fields, unsigned int n_fields); struct synth_event; struct synth_event_trace_state { struct trace_event_buffer fbuffer; struct synth_trace_event *entry; struct trace_buffer *buffer; struct synth_event *event; unsigned int cur_field; unsigned int n_u64; bool disabled; bool add_next; bool add_name; }; extern int synth_event_trace(struct trace_event_file *file, unsigned int n_vals, ...); extern int synth_event_trace_array(struct trace_event_file *file, u64 *vals, unsigned int n_vals); extern int synth_event_trace_start(struct trace_event_file *file, struct synth_event_trace_state *trace_state); extern int synth_event_add_next_val(u64 val, struct synth_event_trace_state *trace_state); extern int synth_event_add_val(const char *field_name, u64 val, struct synth_event_trace_state *trace_state); extern int synth_event_trace_end(struct synth_event_trace_state *trace_state); extern int kprobe_event_delete(const char *name); extern void kprobe_event_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen); extern int __kprobe_event_gen_cmd_start(struct dynevent_cmd *cmd, bool kretprobe, const char *name, const char *loc, ...); extern int __kprobe_event_add_fields(struct dynevent_cmd *cmd, ...); enum { EVENT_FILE_FL_ENABLED = (1 << EVENT_FILE_FL_ENABLED_BIT), EVENT_FILE_FL_RECORDED_CMD = (1 << EVENT_FILE_FL_RECORDED_CMD_BIT), EVENT_FILE_FL_RECORDED_TGID = (1 << EVENT_FILE_FL_RECORDED_TGID_BIT), EVENT_FILE_FL_FILTERED = (1 << EVENT_FILE_FL_FILTERED_BIT), EVENT_FILE_FL_NO_SET_FILTER = (1 << EVENT_FILE_FL_NO_SET_FILTER_BIT), EVENT_FILE_FL_SOFT_MODE = (1 << EVENT_FILE_FL_SOFT_MODE_BIT), EVENT_FILE_FL_SOFT_DISABLED = (1 << EVENT_FILE_FL_SOFT_DISABLED_BIT), EVENT_FILE_FL_TRIGGER_MODE = (1 << EVENT_FILE_FL_TRIGGER_MODE_BIT), EVENT_FILE_FL_TRIGGER_COND = (1 << EVENT_FILE_FL_TRIGGER_COND_BIT), EVENT_FILE_FL_PID_FILTER = (1 << EVENT_FILE_FL_PID_FILTER_BIT), EVENT_FILE_FL_WAS_ENABLED = (1 << EVENT_FILE_FL_WAS_ENABLED_BIT), }; struct trace_event_file { struct list_head list; struct trace_event_call *event_call; struct event_filter __rcu *filter; struct dentry *dir; struct trace_array *tr; struct trace_subsystem_dir *system; struct list_head triggers; unsigned long flags; atomic_t sm_ref; atomic_t tm_ref; }; enum event_trigger_type { ETT_NONE = (0), ETT_TRACE_ONOFF = (1 << 0), ETT_SNAPSHOT = (1 << 1), ETT_STACKTRACE = (1 << 2), ETT_EVENT_ENABLE = (1 << 3), ETT_EVENT_HIST = (1 << 4), ETT_HIST_ENABLE = (1 << 5), }; extern int filter_match_preds(struct event_filter *filter, void *rec); extern enum event_trigger_type event_triggers_call(struct trace_event_file *file, void *rec, struct ring_buffer_event *event); extern void event_triggers_post_call(struct trace_event_file *file, enum event_trigger_type tt); bool trace_event_ignore_this_pid(struct trace_event_file *trace_file); static inline bool trace_trigger_soft_disabled(struct trace_event_file *file) { unsigned long eflags = file->flags; if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) { if (eflags & EVENT_FILE_FL_TRIGGER_MODE) event_triggers_call(file, NULL, NULL); if (eflags & EVENT_FILE_FL_SOFT_DISABLED) return true; if (eflags & EVENT_FILE_FL_PID_FILTER) return trace_event_ignore_this_pid(file); } return false; } unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx); int perf_event_attach_bpf_prog(struct perf_event *event, struct bpf_prog *prog); void perf_event_detach_bpf_prog(struct perf_event *event); int perf_event_query_prog_array(struct perf_event *event, void __user *info); int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog); int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog); struct bpf_raw_event_map *bpf_get_raw_tracepoint(const char *name); void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp); int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, u32 *fd_type, const char **buf, u64 *probe_offset, u64 *probe_addr); enum { FILTER_OTHER = 0, FILTER_STATIC_STRING, FILTER_DYN_STRING, FILTER_PTR_STRING, FILTER_TRACE_FN, FILTER_COMM, FILTER_CPU, }; extern int trace_event_raw_init(struct trace_event_call *call); extern int trace_define_field(struct trace_event_call *call, const char *type, const char *name, int offset, int size, int is_signed, int filter_type); extern int trace_add_event_call(struct trace_event_call *call); extern int trace_remove_event_call(struct trace_event_call *call); extern int trace_event_get_offsets(struct trace_event_call *call); int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set); int trace_set_clr_event(const char *system, const char *event, int set); int trace_array_set_clr_event(struct trace_array *tr, const char *system, const char *event, bool enable); struct perf_event; DECLARE_PER_CPU(struct pt_regs, perf_trace_regs); DECLARE_PER_CPU(int, bpf_kprobe_override); extern int perf_trace_init(struct perf_event *event); extern void perf_trace_destroy(struct perf_event *event); extern int perf_trace_add(struct perf_event *event, int flags); extern void perf_trace_del(struct perf_event *event, int flags); extern int perf_kprobe_init(struct perf_event *event, bool is_retprobe); extern void perf_kprobe_destroy(struct perf_event *event); extern int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type, const char **symbol, u64 *probe_offset, u64 *probe_addr, bool perf_type_tracepoint); extern int perf_uprobe_init(struct perf_event *event, unsigned long ref_ctr_offset, bool is_retprobe); extern void perf_uprobe_destroy(struct perf_event *event); extern int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type, const char **filename, u64 *probe_offset, bool perf_type_tracepoint); extern int ftrace_profile_set_filter(struct perf_event *event, int event_id, char *filter_str); extern void ftrace_profile_free_filter(struct perf_event *event); void perf_trace_buf_update(void *record, u16 type); void *perf_trace_buf_alloc(int size, struct pt_regs **regs, int *rctxp); void bpf_trace_run1(struct bpf_prog *prog, u64 arg1); void bpf_trace_run2(struct bpf_prog *prog, u64 arg1, u64 arg2); void bpf_trace_run3(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3); void bpf_trace_run4(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3, u64 arg4); void bpf_trace_run5(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5); void bpf_trace_run6(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6); void bpf_trace_run7(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7); void bpf_trace_run8(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8); void bpf_trace_run9(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8, u64 arg9); void bpf_trace_run10(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8, u64 arg9, u64 arg10); void bpf_trace_run11(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8, u64 arg9, u64 arg10, u64 arg11); void bpf_trace_run12(struct bpf_prog *prog, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12); void perf_trace_run_bpf_submit(void *raw_data, int size, int rctx, struct trace_event_call *call, u64 count, struct pt_regs *regs, struct hlist_head *head, struct task_struct *task); static inline void perf_trace_buf_submit(void *raw_data, int size, int rctx, u16 type, u64 count, struct pt_regs *regs, void *head, struct task_struct *task) { perf_tp_event(type, count, raw_data, size, regs, head, rctx, task); } static const char str__binder__trace_system_name[] = "binder"; /* EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_set_priority); 宏展开: */ EXPORT_SYMBOL_GPL(__tracepoint_android_vh_binder_set_priority); EXPORT_SYMBOL_GPL(__traceiter_android_vh_binder_set_priority); EXPORT_SYMBOL_GPL(STATIC_CALL_KEY(tp_func_android_vh_binder_set_priority));
四、补充
1. EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_set_priority) 导出了可以给ko使用三个符号。
2. 若想新增导出一个hook给ko驱动使用,除了上面 binder.c、vendor_hooks.c 和 trace/hooks/binder.h 中的改动外,还需要改动 abi_gki_aarch64_<vendor>_whitelist 这个白名单,加上 __tracepoint_android_vh_binder_set_priority。
标签:11,ftrace,struct,trace,int,void,event,tracepoint,DECLARE From: https://www.cnblogs.com/hellokitty2/p/16838490.html