temporary workaround for derefs on arm32
[platform/upstream/bcc.git] / tools / dbus-connection-message-size.c
1 #include <uapi/linux/ptrace.h>
2 #include <linux/sched.h>
3
4 struct DBusString {
5         void *str;
6         int len;
7         unsigned int allocated;
8         unsigned int constant : 1;
9         unsigned int locked : 1;
10         unsigned int invalid : 1;
11         unsigned int align_offset : 3;
12 };
13
14 struct DBusHeaderFields {
15         int value_pos;
16 };
17
18 struct DBusHeader {
19         struct DBusString data;
20
21         struct DBusHeaderFields fields[9];
22
23         u32 padding;
24         u32 byte_order;
25         unsigned char protocol_version;
26 };
27
28 struct DBusMessage {
29         int refcount;
30         struct DBusHeader header;
31         struct DBusString body;
32
33         unsigned int locked : 1;
34
35         void * list;
36         long size_counter_delta;
37         int timeout_ms;
38
39         u32 changed_stamp : 21;
40         void *slot_list;
41
42         int generation;
43
44         int *unix_fds;
45
46         unsigned n_unix_fds;
47         unsigned n_unix_fds_allocated;
48
49         long unix_fd_counter_delta;
50
51         struct DBusString *signature;
52         struct DBusString *unique_sender;
53         size_t gvariant_body_last_offset;
54         size_t gvariant_body_last_pos;
55 };
56
57 struct data_t {
58         u32 pid;
59         char comm[TASK_COMM_LEN];
60 };
61
62 struct bytes_t {
63         int bytes;
64 };
65
66 BPF_HASH(g_message, struct data_t, unsigned long *);
67 BPF_HASH(msg_size, struct data_t, struct bytes_t);
68 BPF_HISTOGRAM(msg_size_hist);
69
70 static int get_process_data(struct data_t *data) {
71         data->pid = bpf_get_current_pid_tgid();
72         bpf_get_current_comm(&data->comm, sizeof(data->comm));
73         return 0;
74 }
75
76 static int message_size(unsigned long size) {
77         struct data_t data = {};
78         get_process_data(&data);
79         if (size != 0) {
80                 msg_size_hist.increment(bpf_log2l(size));
81                 struct bytes_t bytes_sent = {size};
82                 struct bytes_t *bytes_prev = msg_size.lookup(&data);
83                 if (bytes_prev != 0) {
84                         bytes_sent.bytes += bytes_prev->bytes;
85                         msg_size.update(&data, &bytes_sent);
86                 }
87                 else {
88                         msg_size.insert(&data, &bytes_sent);
89                 }
90         }
91         return 0;
92 }
93
94 int g_get_size_pointer (struct pt_regs *ctx, void *dummy, unsigned long *size) {
95         struct data_t data = {};
96         get_process_data(&data);
97         g_message.insert(&data, &size);
98         return 0;
99 }
100
101 int g_get_message_size(struct pt_regs *ctx) {
102         struct data_t data = {};
103         get_process_data(&data);
104         unsigned long **ptr_gsize;
105         ptr_gsize = g_message.lookup(&data);
106         if (ptr_gsize == 0) {
107                 return 0;
108         }
109         unsigned long *gsize = 0;
110         bpf_probe_read(&gsize, sizeof(gsize), ptr_gsize);
111         unsigned long size  = 0;
112         bpf_probe_read(&size, sizeof(size), gsize);
113         if(size > 0 && size < 1000000) {
114                 message_size(size);
115         }
116         return 0;
117 }
118
119 int dbus_message_size(struct pt_regs *ctx, void *conn, struct DBusMessage *message) {
120         unsigned long size = 0;
121         int header_len = 0;
122         int body_len = 0;
123
124         bpf_probe_read(&header_len, sizeof(header_len), (char*)message + offsetof(struct DBusMessage, header.data.len));
125         if (header_len > 0) {
126                 size += header_len;
127         }
128         bpf_probe_read(&body_len, sizeof(body_len), (char*)message + offsetof(struct DBusMessage, body.len));
129         if (body_len > 0) {
130                 size += body_len;
131         }
132         if (size != 0) {
133                 message_size(size);
134         }
135         return 0;
136 }