]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bpf: Make find_linfo widely available
authorKumar Kartikeya Dwivedi <memxor@gmail.com>
Wed, 8 Apr 2026 02:13:54 +0000 (04:13 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 9 Apr 2026 01:09:56 +0000 (18:09 -0700)
Move find_linfo() as bpf_find_linfo() into core.c to allow for its use
in the verifier in subsequent patches.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Link: https://lore.kernel.org/r/20260408021359.3786905-4-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/linux/bpf.h
kernel/bpf/core.c
kernel/bpf/log.c

index d8fb9d61f5cee624e8944c4ab83163a87d3f0446..0136a108d083768cfdde829e96e1c2ea4bb15104 100644 (file)
@@ -3945,6 +3945,7 @@ static inline bool bpf_is_subprog(const struct bpf_prog *prog)
        return prog->aux->func_idx != 0;
 }
 
+const struct bpf_line_info *bpf_find_linfo(const struct bpf_prog *prog, u32 insn_off);
 void bpf_get_linfo_file_line(struct btf *btf, const struct bpf_line_info *linfo,
                             const char **filep, const char **linep, int *nump);
 int bpf_prog_get_file_line(struct bpf_prog *prog, unsigned long ip, const char **filep,
index ada76f99717743315683399ad13606021a2b0461..066b86e7233c47cba7d94cb0049dcf061aec2662 100644 (file)
@@ -3335,6 +3335,43 @@ void bpf_get_linfo_file_line(struct btf *btf, const struct bpf_line_info *linfo,
                *nump = BPF_LINE_INFO_LINE_NUM(linfo->line_col);
 }
 
+const struct bpf_line_info *bpf_find_linfo(const struct bpf_prog *prog, u32 insn_off)
+{
+       const struct bpf_line_info *linfo;
+       u32 nr_linfo;
+       int l, r, m;
+
+       nr_linfo = prog->aux->nr_linfo;
+       if (!nr_linfo || insn_off >= prog->len)
+               return NULL;
+
+       linfo = prog->aux->linfo;
+       /* Loop invariant: linfo[l].insn_off <= insns_off.
+        * linfo[0].insn_off == 0 which always satisfies above condition.
+        * Binary search is searching for rightmost linfo entry that satisfies
+        * the above invariant, giving us the desired record that covers given
+        * instruction offset.
+        */
+       l = 0;
+       r = nr_linfo - 1;
+       while (l < r) {
+               /* (r - l + 1) / 2 means we break a tie to the right, so if:
+                * l=1, r=2, linfo[l].insn_off <= insn_off, linfo[r].insn_off > insn_off,
+                * then m=2, we see that linfo[m].insn_off > insn_off, and so
+                * r becomes 1 and we exit the loop with correct l==1.
+                * If the tie was broken to the left, m=1 would end us up in
+                * an endless loop where l and m stay at 1 and r stays at 2.
+                */
+               m = l + (r - l + 1) / 2;
+               if (linfo[m].insn_off <= insn_off)
+                       l = m;
+               else
+                       r = m - 1;
+       }
+
+       return &linfo[l];
+}
+
 int bpf_prog_get_file_line(struct bpf_prog *prog, unsigned long ip, const char **filep,
                           const char **linep, int *nump)
 {
index 37d72b0521920daf6f3274ad77d055c8b3aafa1b..6fd030fd6eeb9db04f256d23bbc2703d300a16d4 100644 (file)
@@ -329,47 +329,6 @@ __printf(2, 3) void bpf_log(struct bpf_verifier_log *log,
 }
 EXPORT_SYMBOL_GPL(bpf_log);
 
-static const struct bpf_line_info *
-find_linfo(const struct bpf_verifier_env *env, u32 insn_off)
-{
-       const struct bpf_line_info *linfo;
-       const struct bpf_prog *prog;
-       u32 nr_linfo;
-       int l, r, m;
-
-       prog = env->prog;
-       nr_linfo = prog->aux->nr_linfo;
-
-       if (!nr_linfo || insn_off >= prog->len)
-               return NULL;
-
-       linfo = prog->aux->linfo;
-       /* Loop invariant: linfo[l].insn_off <= insns_off.
-        * linfo[0].insn_off == 0 which always satisfies above condition.
-        * Binary search is searching for rightmost linfo entry that satisfies
-        * the above invariant, giving us the desired record that covers given
-        * instruction offset.
-        */
-       l = 0;
-       r = nr_linfo - 1;
-       while (l < r) {
-               /* (r - l + 1) / 2 means we break a tie to the right, so if:
-                * l=1, r=2, linfo[l].insn_off <= insn_off, linfo[r].insn_off > insn_off,
-                * then m=2, we see that linfo[m].insn_off > insn_off, and so
-                * r becomes 1 and we exit the loop with correct l==1.
-                * If the tie was broken to the left, m=1 would end us up in
-                * an endless loop where l and m stay at 1 and r stays at 2.
-                */
-               m = l + (r - l + 1) / 2;
-               if (linfo[m].insn_off <= insn_off)
-                       l = m;
-               else
-                       r = m - 1;
-       }
-
-       return &linfo[l];
-}
-
 static const char *ltrim(const char *s)
 {
        while (isspace(*s))
@@ -390,7 +349,7 @@ __printf(3, 4) void verbose_linfo(struct bpf_verifier_env *env,
                return;
 
        prev_linfo = env->prev_linfo;
-       linfo = find_linfo(env, insn_off);
+       linfo = bpf_find_linfo(env->prog, insn_off);
        if (!linfo || linfo == prev_linfo)
                return;