Skip to content

Commit f67d5bf

Browse files
committed
ci: split tools-resolve_btfids-fix-cross-compilation-to-non-host-endianness in 2
https://github.com/libbpf/ci/blob/main/patch-kernel/patch_kernel.sh would otherwise fail to apply it because one hunk would fail during dry-run. Signed-off-by: Manu Bretelle <[email protected]>
1 parent 76b67d7 commit f67d5bf

File tree

2 files changed

+124
-121
lines changed

2 files changed

+124
-121
lines changed
Lines changed: 7 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
From 9707ac4fe2f5bac6406d2403f8b8a64d7b3d8e43 Mon Sep 17 00:00:00 2001
1+
From 3772e6cdb51f21a11df2acf6aa431cc8b9137bfb Mon Sep 17 00:00:00 2001
22
From: Viktor Malik <[email protected]>
33
Date: Tue, 6 Feb 2024 13:46:09 +0100
4-
Subject: tools/resolve_btfids: Refactor set sorting with types from btf_ids.h
4+
Subject: [PATCH 1/2] tools/resolve_btfids: Refactor set sorting with types
5+
from btf_ids.h
56

67
Instead of using magic offsets to access BTF ID set data, leverage types
78
from btf_ids.h (btf_id_set and btf_id_set8) which define the actual
@@ -19,12 +20,12 @@ Signed-off-by: Andrii Nakryiko <[email protected]>
1920
Acked-by: Daniel Xu <[email protected]>
2021
Link: https://lore.kernel.org/bpf/ff7f062ddf6a00815fda3087957c4ce667f50532.1707223196.git.vmalik@redhat.com
2122
---
22-
tools/bpf/resolve_btfids/main.c | 35 +++++++++++++++++++++--------------
23+
tools/bpf/resolve_btfids/main.c | 35 ++++++++++++++++++++-------------
2324
tools/include/linux/btf_ids.h | 9 +++++++++
2425
2 files changed, 30 insertions(+), 14 deletions(-)
2526

2627
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
27-
index 27a23196d58e10..32634f00abba4a 100644
28+
index 27a23196d58e..32634f00abba 100644
2829
--- a/tools/bpf/resolve_btfids/main.c
2930
+++ b/tools/bpf/resolve_btfids/main.c
3031
@@ -70,6 +70,7 @@
@@ -115,7 +116,7 @@ index 27a23196d58e10..32634f00abba4a 100644
115116
next = rb_next(next);
116117
}
117118
diff --git a/tools/include/linux/btf_ids.h b/tools/include/linux/btf_ids.h
118-
index 2f882d5cb30f5c..72535f00572f6e 100644
119+
index 2f882d5cb30f..72535f00572f 100644
119120
--- a/tools/include/linux/btf_ids.h
120121
+++ b/tools/include/linux/btf_ids.h
121122
@@ -8,6 +8,15 @@ struct btf_id_set {
@@ -135,122 +136,7 @@ index 2f882d5cb30f5c..72535f00572f6e 100644
135136

136137
#include <linux/compiler.h> /* for __PASTE */
137138
--
138-
cgit 1.2.3-korg
139+
2.39.3
139140

140141

141-
From 903fad4394666bc23975c93fb58f137ce64b5192 Mon Sep 17 00:00:00 2001
142-
From: Viktor Malik <[email protected]>
143-
Date: Tue, 6 Feb 2024 13:46:10 +0100
144-
Subject: tools/resolve_btfids: Fix cross-compilation to non-host endianness
145-
146-
The .BTF_ids section is pre-filled with zeroed BTF ID entries during the
147-
build and afterwards patched by resolve_btfids with correct values.
148-
Since resolve_btfids always writes in host-native endianness, it relies
149-
on libelf to do the translation when the target ELF is cross-compiled to
150-
a different endianness (this was introduced in commit 61e8aeda9398
151-
("bpf: Fix libelf endian handling in resolv_btfids")).
152-
153-
Unfortunately, the translation will corrupt the flags fields of SET8
154-
entries because these were written during vmlinux compilation and are in
155-
the correct endianness already. This will lead to numerous selftests
156-
failures such as:
157-
158-
$ sudo ./test_verifier 502 502
159-
#502/p sleepable fentry accept FAIL
160-
Failed to load prog 'Invalid argument'!
161-
bpf_fentry_test1 is not sleepable
162-
verification time 34 usec
163-
stack depth 0
164-
processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
165-
Summary: 0 PASSED, 0 SKIPPED, 1 FAILED
166-
167-
Since it's not possible to instruct libelf to translate just certain
168-
values, let's manually bswap the flags (both global and entry flags) in
169-
resolve_btfids when needed, so that libelf then translates everything
170-
correctly.
171-
172-
Fixes: ef2c6f370a63 ("tools/resolve_btfids: Add support for 8-byte BTF sets")
173-
Signed-off-by: Viktor Malik <[email protected]>
174-
Signed-off-by: Andrii Nakryiko <[email protected]>
175-
Link: https://lore.kernel.org/bpf/7b6bff690919555574ce0f13d2a5996cacf7bf69.1707223196.git.vmalik@redhat.com
176-
---
177-
tools/bpf/resolve_btfids/main.c | 35 +++++++++++++++++++++++++++++++++++
178-
1 file changed, 35 insertions(+)
179-
180-
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
181-
index 32634f00abba4a..d9520cb826b31f 100644
182-
--- a/tools/bpf/resolve_btfids/main.c
183-
+++ b/tools/bpf/resolve_btfids/main.c
184-
@@ -90,6 +90,14 @@
185-
186-
#define ADDR_CNT 100
187-
188-
+#if __BYTE_ORDER == __LITTLE_ENDIAN
189-
+# define ELFDATANATIVE ELFDATA2LSB
190-
+#elif __BYTE_ORDER == __BIG_ENDIAN
191-
+# define ELFDATANATIVE ELFDATA2MSB
192-
+#else
193-
+# error "Unknown machine endianness!"
194-
+#endif
195-
+
196-
struct btf_id {
197-
struct rb_node rb_node;
198-
char *name;
199-
@@ -117,6 +125,7 @@ struct object {
200-
int idlist_shndx;
201-
size_t strtabidx;
202-
unsigned long idlist_addr;
203-
+ int encoding;
204-
} efile;
205-
206-
struct rb_root sets;
207-
@@ -320,6 +329,7 @@ static int elf_collect(struct object *obj)
208-
{
209-
Elf_Scn *scn = NULL;
210-
size_t shdrstrndx;
211-
+ GElf_Ehdr ehdr;
212-
int idx = 0;
213-
Elf *elf;
214-
int fd;
215-
@@ -351,6 +361,13 @@ static int elf_collect(struct object *obj)
216-
return -1;
217-
}
218-
219-
+ if (gelf_getehdr(obj->efile.elf, &ehdr) == NULL) {
220-
+ pr_err("FAILED cannot get ELF header: %s\n",
221-
+ elf_errmsg(-1));
222-
+ return -1;
223-
+ }
224-
+ obj->efile.encoding = ehdr.e_ident[EI_DATA];
225-
+
226-
/*
227-
* Scan all the elf sections and look for save data
228-
* from .BTF_ids section and symbols.
229-
@@ -681,6 +698,24 @@ static int sets_patch(struct object *obj)
230-
*/
231-
BUILD_BUG_ON(set8->pairs != &set8->pairs[0].id);
232-
qsort(set8->pairs, set8->cnt, sizeof(set8->pairs[0]), cmp_id);
233-
+
234-
+ /*
235-
+ * When ELF endianness does not match endianness of the
236-
+ * host, libelf will do the translation when updating
237-
+ * the ELF. This, however, corrupts SET8 flags which are
238-
+ * already in the target endianness. So, let's bswap
239-
+ * them to the host endianness and libelf will then
240-
+ * correctly translate everything.
241-
+ */
242-
+ if (obj->efile.encoding != ELFDATANATIVE) {
243-
+ int i;
244-
+
245-
+ set8->flags = bswap_32(set8->flags);
246-
+ for (i = 0; i < set8->cnt; i++) {
247-
+ set8->pairs[i].flags =
248-
+ bswap_32(set8->pairs[i].flags);
249-
+ }
250-
+ }
251-
}
252-
253-
pr_debug("sorting addr %5lu: cnt %6d [%s]\n",
254-
--
255-
cgit 1.2.3-korg
256142

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
From c3dcadfdf2bf8f01471066700c098b5185240df6 Mon Sep 17 00:00:00 2001
2+
From: Viktor Malik <[email protected]>
3+
Date: Tue, 6 Feb 2024 13:46:10 +0100
4+
Subject: [PATCH 2/2] tools/resolve_btfids: Fix cross-compilation to non-host
5+
endianness
6+
7+
The .BTF_ids section is pre-filled with zeroed BTF ID entries during the
8+
build and afterwards patched by resolve_btfids with correct values.
9+
Since resolve_btfids always writes in host-native endianness, it relies
10+
on libelf to do the translation when the target ELF is cross-compiled to
11+
a different endianness (this was introduced in commit 61e8aeda9398
12+
("bpf: Fix libelf endian handling in resolv_btfids")).
13+
14+
Unfortunately, the translation will corrupt the flags fields of SET8
15+
entries because these were written during vmlinux compilation and are in
16+
the correct endianness already. This will lead to numerous selftests
17+
failures such as:
18+
19+
$ sudo ./test_verifier 502 502
20+
#502/p sleepable fentry accept FAIL
21+
Failed to load prog 'Invalid argument'!
22+
bpf_fentry_test1 is not sleepable
23+
verification time 34 usec
24+
stack depth 0
25+
processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
26+
Summary: 0 PASSED, 0 SKIPPED, 1 FAILED
27+
28+
Since it's not possible to instruct libelf to translate just certain
29+
values, let's manually bswap the flags (both global and entry flags) in
30+
resolve_btfids when needed, so that libelf then translates everything
31+
correctly.
32+
33+
Fixes: ef2c6f370a63 ("tools/resolve_btfids: Add support for 8-byte BTF sets")
34+
Signed-off-by: Viktor Malik <[email protected]>
35+
Signed-off-by: Andrii Nakryiko <[email protected]>
36+
Link: https://lore.kernel.org/bpf/7b6bff690919555574ce0f13d2a5996cacf7bf69.1707223196.git.vmalik@redhat.com
37+
---
38+
tools/bpf/resolve_btfids/main.c | 35 +++++++++++++++++++++++++++++++++
39+
1 file changed, 35 insertions(+)
40+
41+
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
42+
index 32634f00abba..d9520cb826b3 100644
43+
--- a/tools/bpf/resolve_btfids/main.c
44+
+++ b/tools/bpf/resolve_btfids/main.c
45+
@@ -90,6 +90,14 @@
46+
47+
#define ADDR_CNT 100
48+
49+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
50+
+# define ELFDATANATIVE ELFDATA2LSB
51+
+#elif __BYTE_ORDER == __BIG_ENDIAN
52+
+# define ELFDATANATIVE ELFDATA2MSB
53+
+#else
54+
+# error "Unknown machine endianness!"
55+
+#endif
56+
+
57+
struct btf_id {
58+
struct rb_node rb_node;
59+
char *name;
60+
@@ -117,6 +125,7 @@ struct object {
61+
int idlist_shndx;
62+
size_t strtabidx;
63+
unsigned long idlist_addr;
64+
+ int encoding;
65+
} efile;
66+
67+
struct rb_root sets;
68+
@@ -320,6 +329,7 @@ static int elf_collect(struct object *obj)
69+
{
70+
Elf_Scn *scn = NULL;
71+
size_t shdrstrndx;
72+
+ GElf_Ehdr ehdr;
73+
int idx = 0;
74+
Elf *elf;
75+
int fd;
76+
@@ -351,6 +361,13 @@ static int elf_collect(struct object *obj)
77+
return -1;
78+
}
79+
80+
+ if (gelf_getehdr(obj->efile.elf, &ehdr) == NULL) {
81+
+ pr_err("FAILED cannot get ELF header: %s\n",
82+
+ elf_errmsg(-1));
83+
+ return -1;
84+
+ }
85+
+ obj->efile.encoding = ehdr.e_ident[EI_DATA];
86+
+
87+
/*
88+
* Scan all the elf sections and look for save data
89+
* from .BTF_ids section and symbols.
90+
@@ -681,6 +698,24 @@ static int sets_patch(struct object *obj)
91+
*/
92+
BUILD_BUG_ON(set8->pairs != &set8->pairs[0].id);
93+
qsort(set8->pairs, set8->cnt, sizeof(set8->pairs[0]), cmp_id);
94+
+
95+
+ /*
96+
+ * When ELF endianness does not match endianness of the
97+
+ * host, libelf will do the translation when updating
98+
+ * the ELF. This, however, corrupts SET8 flags which are
99+
+ * already in the target endianness. So, let's bswap
100+
+ * them to the host endianness and libelf will then
101+
+ * correctly translate everything.
102+
+ */
103+
+ if (obj->efile.encoding != ELFDATANATIVE) {
104+
+ int i;
105+
+
106+
+ set8->flags = bswap_32(set8->flags);
107+
+ for (i = 0; i < set8->cnt; i++) {
108+
+ set8->pairs[i].flags =
109+
+ bswap_32(set8->pairs[i].flags);
110+
+ }
111+
+ }
112+
}
113+
114+
pr_debug("sorting addr %5lu: cnt %6d [%s]\n",
115+
--
116+
2.39.3
117+

0 commit comments

Comments
 (0)