-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathctf.c
148 lines (136 loc) · 3.81 KB
/
ctf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "ctf.h"
#include "metadata.h"
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <threads.h>
#include <time.h>
#include <unistd.h>
unsigned long start_time = 0;
unsigned long end_time = 0;
char trace_folder[256];
_Thread_local int pos = HEADER_SIZE;
_Thread_local unsigned char packet[PACKET_SIZE];
_Thread_local struct timespec now;
int add_event(unsigned char *packet, int position, int entry,
unsigned long time, long address, unsigned char tid,
unsigned char pid);
int add_event_2(int type, long address) {
timespec_get(&now, TIME_UTC);
unsigned long time = now.tv_sec;
time *= 1e9;
time += now.tv_nsec;
pos = add_event(packet, pos, type, time, address, 0, 0); // get TID and PID if we're doing that
return pos;
}
int trace_entry(unsigned long address) { return add_event_2(0, address); }
int trace_exit(unsigned long address) { return add_event_2(1, 0); }
void init_trace(char *folder) {
struct stat st = {0};
strcpy(trace_folder, folder);
if (stat(folder, &st) == -1) {
mkdir(folder, 0700);
}
char file_name[200];
strcpy(file_name, "./");
strcat(file_name, folder);
strcat(file_name, "/metadata");
FILE *fp = fopen(file_name, "w");
fputs(metadata, fp); // warning because xxd makes an unsigned char[] instead of char[]
fclose(fp);
strcpy(file_name, "./");
strcat(file_name, folder);
strcat(file_name, "/stream"); // Need to add ThreadID if we're doing that
remove(file_name);
}
void write_packet(char *folder, unsigned char *packet, int size, long lost,
long cpu) {
FILE *stream_file;
char file_name[200];
strcpy(file_name, "./");
strcat(file_name, folder);
strcat(file_name, "/stream"); // Need to add ThreadID if we're doing that
stream_file = fopen(file_name, "aw");
// Magic number
int position = 0;
packet[position++] = 0xc1;
packet[position++] = 0x1f;
packet[position++] = 0xfc;
packet[position++] = 0xc1;
// UUID
for (int i = 0; i < 16; i++) {
packet[position++] = 0xaa;
}
// stream ID
packet[position++] = 0;
packet[position++] = 0;
packet[position++] = 0;
packet[position++] = 0;
// Start time
for (int i = 0; i < 8; i++) {
packet[position++] = start_time & 0xff;
start_time = start_time >> 8;
}
// End time
for (int i = 0; i < 8; i++) {
packet[position++] = end_time & 0xff;
end_time = end_time >> 8;
}
int content = size * 8;
int payload = PACKET_SIZE * 8;
// content
for (int i = 0; i < 8; i++) {
packet[position++] = content & 0xff;
content = content >> 8;
}
// size
for (int i = 0; i < 8; i++) {
packet[position++] = payload & 0xff;
payload = payload >> 8;
}
// lost events and CPU
for (int i = 0; i < 12; i++) {
packet[position++] = 0;
}
if (!fwrite(packet, 1, PACKET_SIZE, stream_file)) {
printf("Error on write packet");
}
fclose(stream_file);
}
int add_event(unsigned char *packet, int position, int entry,
unsigned long time, long address, unsigned char tid,
unsigned char pid) {
if (position > 65000) {
write_packet(trace_folder, packet, position, 0, 0);
memset(packet, 0, PAYLOAD_SIZE);
position = HEADER_SIZE;
}
if (start_time == 0) {
start_time = time;
}
if (time > end_time) {
end_time = time;
}
packet[position++] = entry != 0;
for (int i = 0; i < 8; i++) {
packet[position++] = 0xff & time;
time = time >> 8;
}
if (entry == 0) {
for (int i = 0; i < 8; i++) {
packet[position++] = 0xff & address;
address = address >> 8;
}
}
for (int i = 0; i < 1; i++) {
packet[position++] = 0xff & tid;
tid = tid >> 8;
}
for (int i = 0; i < 1; i++) {
packet[position++] = 0xff & pid;
pid = pid >> 8;
}
return position;
}
void flush() { write_packet(trace_folder, packet, pos, 0, 0); }