Skip to content

Commit a6ed383

Browse files
borkmanndavem330
authored andcommitted
bpf_jit_disasm: also support reading jit dump from file
This patch adds support to read the dmesg BPF JIT dump also from a file instead of the klog buffer. I found this quite useful when going through some 'before/after patch' logs. It also fixes a regex leak found by valgrind when no image dump was found. Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1df33a1 commit a6ed383

File tree

1 file changed

+90
-19
lines changed

1 file changed

+90
-19
lines changed

tools/net/bpf_jit_disasm.c

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@
2222
#include <string.h>
2323
#include <bfd.h>
2424
#include <dis-asm.h>
25+
#include <regex.h>
26+
#include <fcntl.h>
2527
#include <sys/klog.h>
2628
#include <sys/types.h>
27-
#include <regex.h>
29+
#include <sys/stat.h>
30+
31+
#define CMD_ACTION_SIZE_BUFFER 10
32+
#define CMD_ACTION_READ_ALL 3
2833

2934
static void get_exec_path(char *tpath, size_t size)
3035
{
@@ -87,20 +92,66 @@ static void get_asm_insns(uint8_t *image, size_t len, int opcodes)
8792
bfd_close(bfdf);
8893
}
8994

90-
static char *get_klog_buff(int *klen)
95+
static char *get_klog_buff(unsigned int *klen)
9196
{
92-
int ret, len = klogctl(10, NULL, 0);
93-
char *buff = malloc(len);
97+
int ret, len;
98+
char *buff;
99+
100+
len = klogctl(CMD_ACTION_SIZE_BUFFER, NULL, 0);
101+
buff = malloc(len);
102+
if (!buff)
103+
return NULL;
104+
105+
ret = klogctl(CMD_ACTION_READ_ALL, buff, len);
106+
if (ret < 0) {
107+
free(buff);
108+
return NULL;
109+
}
94110

95-
assert(buff && klen);
96-
ret = klogctl(3, buff, len);
97-
assert(ret >= 0);
98111
*klen = ret;
112+
return buff;
113+
}
99114

115+
static char *get_flog_buff(const char *file, unsigned int *klen)
116+
{
117+
int fd, ret, len;
118+
struct stat fi;
119+
char *buff;
120+
121+
fd = open(file, O_RDONLY);
122+
if (fd < 0)
123+
return NULL;
124+
125+
ret = fstat(fd, &fi);
126+
if (ret < 0 || !S_ISREG(fi.st_mode))
127+
goto out;
128+
129+
len = fi.st_size + 1;
130+
buff = malloc(len);
131+
if (!buff)
132+
goto out;
133+
134+
memset(buff, 0, len);
135+
ret = read(fd, buff, len - 1);
136+
if (ret <= 0)
137+
goto out_free;
138+
139+
close(fd);
140+
*klen = ret;
100141
return buff;
142+
out_free:
143+
free(buff);
144+
out:
145+
close(fd);
146+
return NULL;
147+
}
148+
149+
static char *get_log_buff(const char *file, unsigned int *klen)
150+
{
151+
return file ? get_flog_buff(file, klen) : get_klog_buff(klen);
101152
}
102153

103-
static void put_klog_buff(char *buff)
154+
static void put_log_buff(char *buff)
104155
{
105156
free(buff);
106157
}
@@ -138,8 +189,10 @@ static int get_last_jit_image(char *haystack, size_t hlen,
138189
ptr = haystack + off - (pmatch[0].rm_eo - pmatch[0].rm_so);
139190
ret = sscanf(ptr, "flen=%d proglen=%d pass=%d image=%lx",
140191
&flen, &proglen, &pass, &base);
141-
if (ret != 4)
192+
if (ret != 4) {
193+
regfree(&regex);
142194
return 0;
195+
}
143196

144197
tmp = ptr = haystack + off;
145198
while ((ptr = strtok(tmp, "\n")) != NULL && ulen < ilen) {
@@ -169,31 +222,49 @@ static int get_last_jit_image(char *haystack, size_t hlen,
169222
return ulen;
170223
}
171224

225+
static void usage(void)
226+
{
227+
printf("Usage: bpf_jit_disasm [...]\n");
228+
printf(" -o Also display related opcodes (default: off).\n");
229+
printf(" -f <file> Read last image dump from file or stdin (default: klog).\n");
230+
printf(" -h Display this help.\n");
231+
}
232+
172233
int main(int argc, char **argv)
173234
{
174-
int len, klen, opcodes = 0;
175-
char *kbuff;
235+
unsigned int len, klen, opt, opcodes = 0;
176236
static uint8_t image[32768];
237+
char *kbuff, *file = NULL;
177238

178-
if (argc > 1) {
179-
if (!strncmp("-o", argv[argc - 1], 2)) {
239+
while ((opt = getopt(argc, argv, "of:")) != -1) {
240+
switch (opt) {
241+
case 'o':
180242
opcodes = 1;
181-
} else {
182-
printf("usage: bpf_jit_disasm [-o: show opcodes]\n");
183-
exit(0);
243+
break;
244+
case 'f':
245+
file = optarg;
246+
break;
247+
default:
248+
usage();
249+
return -1;
184250
}
185251
}
186252

187253
bfd_init();
188254
memset(image, 0, sizeof(image));
189255

190-
kbuff = get_klog_buff(&klen);
256+
kbuff = get_log_buff(file, &klen);
257+
if (!kbuff) {
258+
fprintf(stderr, "Could not retrieve log buffer!\n");
259+
return -1;
260+
}
191261

192262
len = get_last_jit_image(kbuff, klen, image, sizeof(image));
193263
if (len > 0)
194264
get_asm_insns(image, len, opcodes);
265+
else
266+
fprintf(stderr, "No JIT image found!\n");
195267

196-
put_klog_buff(kbuff);
197-
268+
put_log_buff(kbuff);
198269
return 0;
199270
}

0 commit comments

Comments
 (0)