0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define pr_fmt(fmt) "gcov: " fmt
0018
0019 #include <linux/init.h>
0020 #include <linux/module.h>
0021 #include <linux/mutex.h>
0022 #include <linux/sched.h>
0023 #include "gcov.h"
0024
0025 int gcov_events_enabled;
0026 DEFINE_MUTEX(gcov_lock);
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 void gcov_enable_events(void)
0037 {
0038 struct gcov_info *info = NULL;
0039
0040 mutex_lock(&gcov_lock);
0041 gcov_events_enabled = 1;
0042
0043
0044 while ((info = gcov_info_next(info))) {
0045 gcov_event(GCOV_ADD, info);
0046 cond_resched();
0047 }
0048
0049 mutex_unlock(&gcov_lock);
0050 }
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 size_t store_gcov_u32(void *buffer, size_t off, u32 v)
0064 {
0065 u32 *data;
0066
0067 if (buffer) {
0068 data = buffer + off;
0069 *data = v;
0070 }
0071
0072 return sizeof(*data);
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 size_t store_gcov_u64(void *buffer, size_t off, u64 v)
0088 {
0089 u32 *data;
0090
0091 if (buffer) {
0092 data = buffer + off;
0093
0094 data[0] = (v & 0xffffffffUL);
0095 data[1] = (v >> 32);
0096 }
0097
0098 return sizeof(*data) * 2;
0099 }
0100
0101 #ifdef CONFIG_MODULES
0102
0103 static int gcov_module_notifier(struct notifier_block *nb, unsigned long event,
0104 void *data)
0105 {
0106 struct module *mod = data;
0107 struct gcov_info *info = NULL;
0108 struct gcov_info *prev = NULL;
0109
0110 if (event != MODULE_STATE_GOING)
0111 return NOTIFY_OK;
0112 mutex_lock(&gcov_lock);
0113
0114
0115 while ((info = gcov_info_next(info))) {
0116 if (gcov_info_within_module(info, mod)) {
0117 gcov_info_unlink(prev, info);
0118 if (gcov_events_enabled)
0119 gcov_event(GCOV_REMOVE, info);
0120 } else
0121 prev = info;
0122 }
0123
0124 mutex_unlock(&gcov_lock);
0125
0126 return NOTIFY_OK;
0127 }
0128
0129 static struct notifier_block gcov_nb = {
0130 .notifier_call = gcov_module_notifier,
0131 };
0132
0133 static int __init gcov_init(void)
0134 {
0135 return register_module_notifier(&gcov_nb);
0136 }
0137 device_initcall(gcov_init);
0138 #endif