aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2018-11-12 18:44:53 -0500
committerAlexei Starovoitov <ast@kernel.org>2018-11-16 20:46:54 -0500
commita83d6e76a67424ebbbbed643f51e97934ffc2bc2 (patch)
treec9905473ea6cece22d0201c4971b044c575937da
parent5c86d2125b58949122e03f04ce940e6f5b8534ba (diff)
bpf: libbpf: Fix bpf_program__next() API
This patch restores the behavior in commit eac7d84519a3 ("tools: libbpf: don't return '.text' as a program for multi-function programs") such that bpf_program__next() does not return pseudo programs in ".text". Fixes: 0c19a9fbc9cd ("libbpf: cleanup after partial failure in bpf_object__pin") Signed-off-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r--tools/lib/bpf/libbpf.c25
1 files changed, 11 insertions, 14 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index e827542ffa3a..a01eb9584e52 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -2193,19 +2193,25 @@ void *bpf_object__priv(struct bpf_object *obj)
2193} 2193}
2194 2194
2195static struct bpf_program * 2195static struct bpf_program *
2196__bpf_program__iter(struct bpf_program *p, struct bpf_object *obj, int i) 2196__bpf_program__iter(struct bpf_program *p, struct bpf_object *obj, bool forward)
2197{ 2197{
2198 size_t nr_programs = obj->nr_programs;
2198 ssize_t idx; 2199 ssize_t idx;
2199 2200
2200 if (!obj->programs) 2201 if (!nr_programs)
2201 return NULL; 2202 return NULL;
2202 2203
2204 if (!p)
2205 /* Iter from the beginning */
2206 return forward ? &obj->programs[0] :
2207 &obj->programs[nr_programs - 1];
2208
2203 if (p->obj != obj) { 2209 if (p->obj != obj) {
2204 pr_warning("error: program handler doesn't match object\n"); 2210 pr_warning("error: program handler doesn't match object\n");
2205 return NULL; 2211 return NULL;
2206 } 2212 }
2207 2213
2208 idx = (p - obj->programs) + i; 2214 idx = (p - obj->programs) + (forward ? 1 : -1);
2209 if (idx >= obj->nr_programs || idx < 0) 2215 if (idx >= obj->nr_programs || idx < 0)
2210 return NULL; 2216 return NULL;
2211 return &obj->programs[idx]; 2217 return &obj->programs[idx];
@@ -2216,11 +2222,8 @@ bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
2216{ 2222{
2217 struct bpf_program *prog = prev; 2223 struct bpf_program *prog = prev;
2218 2224
2219 if (prev == NULL)
2220 return obj->programs;
2221
2222 do { 2225 do {
2223 prog = __bpf_program__iter(prog, obj, 1); 2226 prog = __bpf_program__iter(prog, obj, true);
2224 } while (prog && bpf_program__is_function_storage(prog, obj)); 2227 } while (prog && bpf_program__is_function_storage(prog, obj));
2225 2228
2226 return prog; 2229 return prog;
@@ -2231,14 +2234,8 @@ bpf_program__prev(struct bpf_program *next, struct bpf_object *obj)
2231{ 2234{
2232 struct bpf_program *prog = next; 2235 struct bpf_program *prog = next;
2233 2236
2234 if (next == NULL) {
2235 if (!obj->nr_programs)
2236 return NULL;
2237 return obj->programs + obj->nr_programs - 1;
2238 }
2239
2240 do { 2237 do {
2241 prog = __bpf_program__iter(prog, obj, -1); 2238 prog = __bpf_program__iter(prog, obj, false);
2242 } while (prog && bpf_program__is_function_storage(prog, obj)); 2239 } while (prog && bpf_program__is_function_storage(prog, obj));
2243 2240
2244 return prog; 2241 return prog;