Skip to content

Commit 3d65014

Browse files
iamkafaiAlexei Starovoitov
authored andcommitted
bpf: libbpf: Add btf_line_info support to libbpf
This patch adds bpf_line_info support to libbpf: 1) Parsing the line_info sec from ".BTF.ext" 2) Relocating the line_info. If the main prog *_info relocation fails, it will ignore the remaining subprog line_info and continue. If the subprog *_info relocation fails, it will bail out. 3) BPF_PROG_LOAD a prog with line_info Signed-off-by: Martin KaFai Lau <kafai@fb.com> Acked-by: Yonghong Song <yhs@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent f0187f0 commit 3d65014

File tree

5 files changed

+239
-89
lines changed

5 files changed

+239
-89
lines changed

tools/lib/bpf/bpf.c

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,36 @@ int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name,
173173
-1);
174174
}
175175

176+
static void *
177+
alloc_zero_tailing_info(const void *orecord, __u32 cnt,
178+
__u32 actual_rec_size, __u32 expected_rec_size)
179+
{
180+
__u64 info_len = actual_rec_size * cnt;
181+
void *info, *nrecord;
182+
int i;
183+
184+
info = malloc(info_len);
185+
if (!info)
186+
return NULL;
187+
188+
/* zero out bytes kernel does not understand */
189+
nrecord = info;
190+
for (i = 0; i < cnt; i++) {
191+
memcpy(nrecord, orecord, expected_rec_size);
192+
memset(nrecord + expected_rec_size, 0,
193+
actual_rec_size - expected_rec_size);
194+
orecord += actual_rec_size;
195+
nrecord += actual_rec_size;
196+
}
197+
198+
return info;
199+
}
200+
176201
int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
177202
char *log_buf, size_t log_buf_sz)
178203
{
204+
void *finfo = NULL, *linfo = NULL;
179205
union bpf_attr attr;
180-
void *finfo = NULL;
181206
__u32 name_len;
182207
int fd;
183208

@@ -201,6 +226,9 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
201226
attr.func_info_rec_size = load_attr->func_info_rec_size;
202227
attr.func_info_cnt = load_attr->func_info_cnt;
203228
attr.func_info = ptr_to_u64(load_attr->func_info);
229+
attr.line_info_rec_size = load_attr->line_info_rec_size;
230+
attr.line_info_cnt = load_attr->line_info_cnt;
231+
attr.line_info = ptr_to_u64(load_attr->line_info);
204232
memcpy(attr.prog_name, load_attr->name,
205233
min(name_len, BPF_OBJ_NAME_LEN - 1));
206234

@@ -212,36 +240,35 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
212240
* to give user space a hint how to deal with loading failure.
213241
* Check to see whether we can make some changes and load again.
214242
*/
215-
if (errno == E2BIG && attr.func_info_cnt &&
216-
attr.func_info_rec_size < load_attr->func_info_rec_size) {
217-
__u32 actual_rec_size = load_attr->func_info_rec_size;
218-
__u32 expected_rec_size = attr.func_info_rec_size;
219-
__u32 finfo_cnt = load_attr->func_info_cnt;
220-
__u64 finfo_len = actual_rec_size * finfo_cnt;
221-
const void *orecord;
222-
void *nrecord;
223-
int i;
224-
225-
finfo = malloc(finfo_len);
226-
if (!finfo)
227-
/* further try with log buffer won't help */
228-
return fd;
229-
230-
/* zero out bytes kernel does not understand */
231-
orecord = load_attr->func_info;
232-
nrecord = finfo;
233-
for (i = 0; i < load_attr->func_info_cnt; i++) {
234-
memcpy(nrecord, orecord, expected_rec_size);
235-
memset(nrecord + expected_rec_size, 0,
236-
actual_rec_size - expected_rec_size);
237-
orecord += actual_rec_size;
238-
nrecord += actual_rec_size;
243+
while (errno == E2BIG && (!finfo || !linfo)) {
244+
if (!finfo && attr.func_info_cnt &&
245+
attr.func_info_rec_size < load_attr->func_info_rec_size) {
246+
/* try with corrected func info records */
247+
finfo = alloc_zero_tailing_info(load_attr->func_info,
248+
load_attr->func_info_cnt,
249+
load_attr->func_info_rec_size,
250+
attr.func_info_rec_size);
251+
if (!finfo)
252+
goto done;
253+
254+
attr.func_info = ptr_to_u64(finfo);
255+
attr.func_info_rec_size = load_attr->func_info_rec_size;
256+
} else if (!linfo && attr.line_info_cnt &&
257+
attr.line_info_rec_size <
258+
load_attr->line_info_rec_size) {
259+
linfo = alloc_zero_tailing_info(load_attr->line_info,
260+
load_attr->line_info_cnt,
261+
load_attr->line_info_rec_size,
262+
attr.line_info_rec_size);
263+
if (!linfo)
264+
goto done;
265+
266+
attr.line_info = ptr_to_u64(linfo);
267+
attr.line_info_rec_size = load_attr->line_info_rec_size;
268+
} else {
269+
break;
239270
}
240271

241-
/* try with corrected func info records */
242-
attr.func_info = ptr_to_u64(finfo);
243-
attr.func_info_rec_size = load_attr->func_info_rec_size;
244-
245272
fd = sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
246273

247274
if (fd >= 0)
@@ -259,6 +286,7 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
259286
fd = sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
260287
done:
261288
free(finfo);
289+
free(linfo);
262290
return fd;
263291
}
264292

tools/lib/bpf/bpf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ struct bpf_load_program_attr {
8282
__u32 func_info_rec_size;
8383
const void *func_info;
8484
__u32 func_info_cnt;
85+
__u32 line_info_rec_size;
86+
const void *line_info;
87+
__u32 line_info_cnt;
8588
};
8689

8790
/* Flags to direct loading requirements */

0 commit comments

Comments
 (0)