7
7
#include <sys/stat.h>
8
8
9
9
#include "frame.piqi.pb-c-patched.h"
10
+ #include "trace_consts.h"
10
11
#include "trace_meta.h"
11
12
12
13
#define MD5LEN 16
13
14
14
- static void compute_target_md5 (const char * binary_path ) {
15
+ static void compute_target_md5 (const char * binary_path ,
16
+ guchar target_md5 [MD5LEN ]) {
15
17
const GChecksumType md5 = G_CHECKSUM_MD5 ;
16
- guchar target_md5 [MD5LEN ];
17
18
18
19
GChecksum * cs = g_checksum_new (md5 );
19
20
FILE * target = fopen (binary_path , "r" );
@@ -38,37 +39,31 @@ static void compute_target_md5(const char *binary_path) {
38
39
fclose (target );
39
40
}
40
41
41
- static void meta_write_header ( FILE * file ) {
42
- // uint64_t toc_off = 0L ;
43
- // WRITE(magic_number );
44
- // WRITE(out_trace_version) ;
45
- // WRITE(frame_arch) ;
46
- // WRITE(frame_mach) ;
47
- // WRITE(toc_num_frames) ;
48
- // WRITE(toc_off );
42
+ static void init_tracer ( Tracer * tracer , char * * argv , int argc ) {
43
+ tracer__init ( tracer ) ;
44
+ tracer -> name = g_strdup ( TRACER_NAME );
45
+ tracer -> n_args = argc ;
46
+ tracer -> args = argv ;
47
+ tracer -> n_envp = 0 ;
48
+ tracer -> envp = NULL ;
49
+ tracer -> version = g_strdup ( TRACER_VERSION );
49
50
}
50
51
51
- static void init_tracer (Tracer * tracer , char * * argv , char * * envp ) {
52
- // tracer__init(tracer);
53
- // tracer->name = tracer_name;
54
- // tracer->n_args = list_length(argv);
55
- // tracer->args = argv;
56
- // tracer->n_envp = list_length(envp);
57
- // tracer->envp = envp;
58
- // tracer->version = tracer_version;
59
- }
52
+ static void init_target (Target * target , const char * bin_path , char * * argv ,
53
+ int argc ) {
54
+ target__init (target );
60
55
61
- static void init_target ( Target * target , char * * argv , char * * envp ) {
62
- // compute_target_md5( );
63
-
64
- // target__init( target);
65
- // target->path = target_path ;
66
- // target->n_args = list_length(argv) ;
67
- // target->args = argv;
68
- // target->n_envp = list_length(envp) ;
69
- // target->envp = envp ;
70
- // target->md5sum.len = MD5LEN ;
71
- // target->md5sum.data = target_md5 ;
56
+ if ( bin_path ) {
57
+ guchar * target_md5 = g_malloc0 ( MD5LEN );
58
+ compute_target_md5 ( bin_path , target_md5 );
59
+ target -> path = g_strdup ( bin_path );
60
+ target -> md5sum . len = MD5LEN ;
61
+ target -> md5sum . data = target_md5 ;
62
+ }
63
+ target -> n_args = argc ;
64
+ target -> args = argv ;
65
+ target -> n_envp = 0 ;
66
+ target -> envp = NULL ;
72
67
}
73
68
74
69
#ifdef G_OS_UNIX
@@ -95,18 +90,74 @@ static bool init_fstats(Fstats *fstats, const char *binary_path) {
95
90
return true;
96
91
}
97
92
98
- static void write_meta (WLOCKED FILE * file , char * * tracer_argv ,
99
- char * * tracer_envp , char * * target_argv ,
100
- char * * target_envp ) {
101
- MetaFrame meta ;
102
- Tracer tracer ;
103
- Target target ;
104
- Fstats fstats ;
93
+ char * get_argv_val (char * * argv , int argc , const char * key ) {
94
+ for (size_t i = 0 ; i < argc ; ++ i ) {
95
+ if (!strncmp (argv [i ], key , strlen (key ))) {
96
+ const char * val = argv [i ] + strlen (key );
97
+ if (val [0 ] != '=' ) {
98
+ qemu_plugin_outs ("Invalid argument value for " );
99
+ qemu_plugin_outs (key );
100
+ qemu_plugin_outs ("\n" );
101
+ qemu_plugin_outs ("Should be 'key=val'\n" );
102
+ return NULL ;
103
+ }
104
+ val ++ ;
105
+ const char * end = strchr (val , ',' );
106
+ while (end && * (end - 1 ) == '\\' ) {
107
+ // Allow escaped commas.
108
+ end = strchr (val , ',' );
109
+ }
110
+ size_t len = !end ? strlen (val ) : end - val ;
111
+ char * argument = g_malloc0 (len + 1 );
112
+ memcpy (argument , val , len );
113
+ return argument ;
114
+ }
115
+ }
116
+ return NULL ;
117
+ }
118
+
119
+ void file_exists_exit (const char * file ) {
120
+ FILE * test = fopen (file , "r" );
121
+ if (!test ) {
122
+ qemu_plugin_outs ("Failed to open binary file: " );
123
+ qemu_plugin_outs (file );
124
+ qemu_plugin_outs ("\n" );
125
+ exit (1 );
126
+ }
127
+ fclose (test );
128
+ }
129
+
130
+ void write_meta (WLOCKED FILE * file , char * * plugin_argv , size_t plugin_argc ) {
131
+ char * arg_bin_path = get_argv_val (plugin_argv , plugin_argc , "bin_path" );
132
+ // Note: Usually we should get the binary path from
133
+ // qemu_plugin_path_to_binary(). But it doesn't seem to work due to dependency
134
+ // issues. See: https://gitlab.com/qemu-project/qemu/-/issues/3014
135
+ const char * bin_path = NULL ; // qemu_plugin_path_to_binary();
136
+ if (!bin_path && !arg_bin_path ) {
137
+ qemu_plugin_outs ("\nFailed to retrieve the binary path\n" );
138
+ qemu_plugin_outs ("This is required.\n" );
139
+ qemu_plugin_outs ("You can pass it as plugin argument "
140
+ "'bin_path=<path>'.\n\n" );
141
+ exit (1 );
142
+ } else {
143
+ file_exists_exit (arg_bin_path );
144
+ }
145
+ if (bin_path && arg_bin_path ) {
146
+ qemu_plugin_outs (
147
+ "'bin_path' argument found, but the binary path is known to the module.\n\
148
+ Argument 'bin_path' is ignored.\n" );
149
+ }
150
+
151
+ MetaFrame meta = {0 };
152
+ Tracer tracer = {0 };
153
+ Target target = {0 };
154
+ Fstats fstats = {0 };
105
155
106
156
meta_frame__init (& meta );
107
- init_tracer (& tracer , tracer_argv , tracer_envp );
108
- init_target (& target , target_argv , target_envp );
109
- init_fstats (& fstats , "target-path" );
157
+ init_tracer (& tracer , plugin_argv , plugin_argc );
158
+ init_target (& target , bin_path ? bin_path : arg_bin_path , plugin_argv ,
159
+ plugin_argc );
160
+ init_fstats (& fstats , bin_path ? bin_path : arg_bin_path );
110
161
111
162
meta .tracer = & tracer ;
112
163
meta .target = & target ;
@@ -119,11 +170,24 @@ static void write_meta(WLOCKED FILE *file, char **tracer_argv,
119
170
meta .host = host ;
120
171
121
172
size_t msg_size = meta_frame__get_packed_size (& meta );
122
- uint8_t * packed_buffer = g_alloca (msg_size );
173
+ uint8_t * packed_buffer = g_malloc0 (msg_size );
123
174
uint64_t packed_size = meta_frame__pack (& meta , packed_buffer );
175
+ g_assert (msg_size == packed_size );
124
176
WRITE (packed_size );
125
- WRITE_BUF (& meta , packed_size );
126
177
127
- free (user );
128
- free (host );
178
+ // I don't know why, but ASAN crashes at this line if the WRITE_BUF macro
179
+ // is used. Although it should be the exact same code.
180
+ if (fwrite ((packed_buffer ), 1 , (packed_size ), file ) != packed_size ) {
181
+ err (1 , "fwrite failed" );
182
+ }
183
+
184
+ g_free (packed_buffer );
185
+ g_free (tracer .name );
186
+ g_free (tracer .version );
187
+ g_free (target .path );
188
+ g_free (target .md5sum .data );
189
+
190
+ g_free (user );
191
+ g_free (host );
192
+ g_free (arg_bin_path );
129
193
}
0 commit comments