30
30
#include "json_writer.h"
31
31
#include "main.h"
32
32
33
+ static int oper_count ;
34
+
35
+ typedef struct {
36
+ struct disassemble_info * info ;
37
+ disassembler_ftype disassemble ;
38
+ bfd * bfdf ;
39
+ } disasm_ctx_t ;
40
+
33
41
static int get_exec_path (char * tpath , size_t size )
34
42
{
35
43
const char * path = "/proc/self/exe" ;
@@ -44,7 +52,6 @@ static int get_exec_path(char *tpath, size_t size)
44
52
return 0 ;
45
53
}
46
54
47
- static int oper_count ;
48
55
static int printf_json (void * out , const char * fmt , va_list ap )
49
56
{
50
57
char * s ;
@@ -102,46 +109,44 @@ static int fprintf_json_styled(void *out,
102
109
return r ;
103
110
}
104
111
105
- int disasm_print_insn (unsigned char * image , ssize_t len , int opcodes ,
106
- const char * arch , const char * disassembler_options ,
107
- const struct btf * btf ,
108
- const struct bpf_prog_linfo * prog_linfo ,
109
- __u64 func_ksym , unsigned int func_idx ,
110
- bool linum )
112
+ static int init_context (disasm_ctx_t * ctx , const char * arch ,
113
+ const char * disassembler_options ,
114
+ unsigned char * image , ssize_t len )
111
115
{
112
- const struct bpf_line_info * linfo = NULL ;
113
- disassembler_ftype disassemble ;
114
- int count , i , pc = 0 , err = -1 ;
115
- struct disassemble_info info ;
116
- unsigned int nr_skip = 0 ;
116
+ struct disassemble_info * info ;
117
117
char tpath [PATH_MAX ];
118
118
bfd * bfdf ;
119
119
120
- if (!len )
121
- return -1 ;
122
-
123
120
memset (tpath , 0 , sizeof (tpath ));
124
121
if (get_exec_path (tpath , sizeof (tpath ))) {
125
122
p_err ("failed to create disasembler (get_exec_path)" );
126
123
return -1 ;
127
124
}
128
125
129
- bfdf = bfd_openr (tpath , NULL );
130
- if (!bfdf ) {
126
+ ctx -> bfdf = bfd_openr (tpath , NULL );
127
+ if (!ctx -> bfdf ) {
131
128
p_err ("failed to create disassembler (bfd_openr)" );
132
129
return -1 ;
133
130
}
134
- if (!bfd_check_format (bfdf , bfd_object )) {
131
+ if (!bfd_check_format (ctx -> bfdf , bfd_object )) {
135
132
p_err ("failed to create disassembler (bfd_check_format)" );
136
- goto exit_close ;
133
+ goto err_close ;
137
134
}
135
+ bfdf = ctx -> bfdf ;
136
+
137
+ ctx -> info = malloc (sizeof (struct disassemble_info ));
138
+ if (!ctx -> info ) {
139
+ p_err ("mem alloc failed" );
140
+ goto err_close ;
141
+ }
142
+ info = ctx -> info ;
138
143
139
144
if (json_output )
140
- init_disassemble_info_compat (& info , stdout ,
145
+ init_disassemble_info_compat (info , stdout ,
141
146
(fprintf_ftype ) fprintf_json ,
142
147
fprintf_json_styled );
143
148
else
144
- init_disassemble_info_compat (& info , stdout ,
149
+ init_disassemble_info_compat (info , stdout ,
145
150
(fprintf_ftype ) fprintf ,
146
151
fprintf_styled );
147
152
@@ -153,31 +158,76 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
153
158
bfdf -> arch_info = inf ;
154
159
} else {
155
160
p_err ("No libbfd support for %s" , arch );
156
- goto exit_close ;
161
+ goto err_free ;
157
162
}
158
163
}
159
164
160
- info . arch = bfd_get_arch (bfdf );
161
- info . mach = bfd_get_mach (bfdf );
165
+ info -> arch = bfd_get_arch (bfdf );
166
+ info -> mach = bfd_get_mach (bfdf );
162
167
if (disassembler_options )
163
- info . disassembler_options = disassembler_options ;
164
- info . buffer = image ;
165
- info . buffer_length = len ;
168
+ info -> disassembler_options = disassembler_options ;
169
+ info -> buffer = image ;
170
+ info -> buffer_length = len ;
166
171
167
- disassemble_init_for_target (& info );
172
+ disassemble_init_for_target (info );
168
173
169
174
#ifdef DISASM_FOUR_ARGS_SIGNATURE
170
- disassemble = disassembler (info . arch ,
171
- bfd_big_endian (bfdf ),
172
- info . mach ,
173
- bfdf );
175
+ ctx -> disassemble = disassembler (info -> arch ,
176
+ bfd_big_endian (bfdf ),
177
+ info -> mach ,
178
+ bfdf );
174
179
#else
175
- disassemble = disassembler (bfdf );
180
+ ctx -> disassemble = disassembler (bfdf );
176
181
#endif
177
- if (!disassemble ) {
182
+ if (!ctx -> disassemble ) {
178
183
p_err ("failed to create disassembler" );
179
- goto exit_close ;
184
+ goto err_free ;
180
185
}
186
+ return 0 ;
187
+
188
+ err_free :
189
+ free (info );
190
+ err_close :
191
+ bfd_close (ctx -> bfdf );
192
+ return -1 ;
193
+ }
194
+
195
+ static void destroy_context (disasm_ctx_t * ctx )
196
+ {
197
+ free (ctx -> info );
198
+ bfd_close (ctx -> bfdf );
199
+ }
200
+
201
+ static int
202
+ disassemble_insn (disasm_ctx_t * ctx , __maybe_unused unsigned char * image ,
203
+ __maybe_unused ssize_t len , int pc )
204
+ {
205
+ return ctx -> disassemble (pc , ctx -> info );
206
+ }
207
+
208
+ int disasm_init (void )
209
+ {
210
+ bfd_init ();
211
+ return 0 ;
212
+ }
213
+
214
+ int disasm_print_insn (unsigned char * image , ssize_t len , int opcodes ,
215
+ const char * arch , const char * disassembler_options ,
216
+ const struct btf * btf ,
217
+ const struct bpf_prog_linfo * prog_linfo ,
218
+ __u64 func_ksym , unsigned int func_idx ,
219
+ bool linum )
220
+ {
221
+ const struct bpf_line_info * linfo = NULL ;
222
+ unsigned int nr_skip = 0 ;
223
+ int count , i , pc = 0 ;
224
+ disasm_ctx_t ctx ;
225
+
226
+ if (!len )
227
+ return -1 ;
228
+
229
+ if (init_context (& ctx , arch , disassembler_options , image , len ))
230
+ return -1 ;
181
231
182
232
if (json_output )
183
233
jsonw_start_array (json_wtr );
@@ -205,7 +255,8 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
205
255
printf ("%4x:\t" , pc );
206
256
}
207
257
208
- count = disassemble (pc , & info );
258
+ count = disassemble_insn (& ctx , image , len , pc );
259
+
209
260
if (json_output ) {
210
261
/* Operand array, was started in fprintf_json. Before
211
262
* that, make sure we have a _null_ value if no operand
@@ -241,15 +292,7 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
241
292
if (json_output )
242
293
jsonw_end_array (json_wtr );
243
294
244
- err = 0 ;
245
-
246
- exit_close :
247
- bfd_close (bfdf );
248
- return err ;
249
- }
295
+ destroy_context (& ctx );
250
296
251
- int disasm_init (void )
252
- {
253
- bfd_init ();
254
297
return 0 ;
255
298
}
0 commit comments