Skip to content

Commit 0e521ef

Browse files
kkdwivediAlexei Starovoitov
authored andcommitted
bpf: Add function to extract program source info
Prepare a function for use in future patches that can extract the file info, line info, and the source line number for a given BPF program provided it's program counter. Only the basename of the file path is provided, given it can be excessively long in some cases. This will be used in later patches to print source info to the BPF stream. Reviewed-by: Emil Tsalapatis <[email protected]> Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 5ab154f commit 0e521ef

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

include/linux/bpf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3661,4 +3661,7 @@ static inline bool bpf_is_subprog(const struct bpf_prog *prog)
36613661
return prog->aux->func_idx != 0;
36623662
}
36633663

3664+
int bpf_prog_get_file_line(struct bpf_prog *prog, unsigned long ip, const char **filep,
3665+
const char **linep, int *nump);
3666+
36643667
#endif /* _LINUX_BPF_H */

kernel/bpf/core.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3213,3 +3213,50 @@ EXPORT_SYMBOL(bpf_stats_enabled_key);
32133213

32143214
EXPORT_TRACEPOINT_SYMBOL_GPL(xdp_exception);
32153215
EXPORT_TRACEPOINT_SYMBOL_GPL(xdp_bulk_tx);
3216+
3217+
#ifdef CONFIG_BPF_SYSCALL
3218+
3219+
int bpf_prog_get_file_line(struct bpf_prog *prog, unsigned long ip, const char **filep,
3220+
const char **linep, int *nump)
3221+
{
3222+
int idx = -1, insn_start, insn_end, len;
3223+
struct bpf_line_info *linfo;
3224+
void **jited_linfo;
3225+
struct btf *btf;
3226+
3227+
btf = prog->aux->btf;
3228+
linfo = prog->aux->linfo;
3229+
jited_linfo = prog->aux->jited_linfo;
3230+
3231+
if (!btf || !linfo || !jited_linfo)
3232+
return -EINVAL;
3233+
len = prog->aux->func ? prog->aux->func[prog->aux->func_idx]->len : prog->len;
3234+
3235+
linfo = &prog->aux->linfo[prog->aux->linfo_idx];
3236+
jited_linfo = &prog->aux->jited_linfo[prog->aux->linfo_idx];
3237+
3238+
insn_start = linfo[0].insn_off;
3239+
insn_end = insn_start + len;
3240+
3241+
for (int i = 0; i < prog->aux->nr_linfo &&
3242+
linfo[i].insn_off >= insn_start && linfo[i].insn_off < insn_end; i++) {
3243+
if (jited_linfo[i] >= (void *)ip)
3244+
break;
3245+
idx = i;
3246+
}
3247+
3248+
if (idx == -1)
3249+
return -ENOENT;
3250+
3251+
/* Get base component of the file path. */
3252+
*filep = btf_name_by_offset(btf, linfo[idx].file_name_off);
3253+
*filep = kbasename(*filep);
3254+
/* Obtain the source line, and strip whitespace in prefix. */
3255+
*linep = btf_name_by_offset(btf, linfo[idx].line_off);
3256+
while (isspace(**linep))
3257+
*linep += 1;
3258+
*nump = BPF_LINE_INFO_LINE_NUM(linfo[idx].line_col);
3259+
return 0;
3260+
}
3261+
3262+
#endif

0 commit comments

Comments
 (0)