* [PATCH dwarves] btf_encoder: Fix handling of percpu symbols on s390
@ 2021-10-12 2:26 Ilya Leoshkevich
2021-10-15 12:54 ` Arnaldo Carvalho de Melo
0 siblings, 1 reply; 2+ messages in thread
From: Ilya Leoshkevich @ 2021-10-12 2:26 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: dwarves, bpf, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich
pahole does not generate VARs for percpu symbols on s390. A percpu
symbol definition on a typical x86_64 kernel looks like this:
[33] .data..percpu PROGBITS 0000000000000000 01c00000
^^^^^^^^^^^^^^^^ sh_addr
LOAD 0x0000000001c00000 0x0000000000000000 0x000000000286f000
^^^^^^^^^^^^^^^^^^ p_vaddr
13559: 000000000001ba50 4 OBJECT LOCAL DEFAULT 33 cpu_profile_flip
^^^^^^^^^^^^^^^^ st_value
Most importantly, .data..percpu's sh_addr is 0, and this is what pahole
is currently assuming. However, on s390 this is different:
[37] .data..percpu PROGBITS 00000000019cd000 018ce000
^^^^^^^^^^^^^^^^ sh_addr
LOAD 0x000000000136e000 0x000000000146d000 0x000000000146d000
^^^^^^^^^^^^^^^^^^ p_vaddr
80377: 0000000001ba1440 4 OBJECT WEAK DEFAULT 37 cpu_profile_flip
^^^^^^^^^^^^^^^^ st_value
Fix by restructuring the code to always use section-relative offsets
for symbols. Change the comment to focus on this invariant.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
btf_encoder.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/btf_encoder.c b/btf_encoder.c
index c341f95..16e90c3 100644
--- a/btf_encoder.c
+++ b/btf_encoder.c
@@ -56,7 +56,8 @@ struct btf_encoder {
raw_output,
verbose,
force,
- gen_floats;
+ gen_floats,
+ is_rel;
uint32_t array_index_id;
struct {
struct var_info vars[MAX_PERCPU_VAR_CNT];
@@ -1104,6 +1105,13 @@ static int btf_encoder__collect_percpu_var(struct btf_encoder *encoder, GElf_Sym
if (encoder->verbose)
printf("Found per-CPU symbol '%s' at address 0x%" PRIx64 "\n", sym_name, addr);
+ /* Make sure addr is section-relative. For kernel modules (which are
+ * ET_REL files) this is already the case. For vmlinux (which is an
+ * ET_EXEC file) we need to subtract the section address.
+ */
+ if (!encoder->is_rel)
+ addr -= encoder->percpu.base_addr;
+
if (encoder->percpu.var_cnt == MAX_PERCPU_VAR_CNT) {
fprintf(stderr, "Reached the limit of per-CPU variables: %d\n",
MAX_PERCPU_VAR_CNT);
@@ -1195,12 +1203,9 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder, struct
addr = var->ip.addr;
dwarf_name = variable__name(var);
- /* DWARF takes into account .data..percpu section offset
- * within its segment, which for vmlinux is 0, but for kernel
- * modules is >0. ELF symbols, on the other hand, don't take
- * into account these offsets (as they are relative to the
- * section start), so to match DWARF and ELF symbols we need
- * to negate the section base address here.
+ /* Make sure addr is section-relative. DWARF, unlike ELF,
+ * always contains virtual symbol addresses, so subtract
+ * the section address unconditionally.
*/
if (addr < encoder->percpu.base_addr || addr >= encoder->percpu.base_addr + encoder->percpu.sec_sz)
continue;
@@ -1322,6 +1327,8 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam
goto out_delete;
}
+ encoder->is_rel = ehdr.e_type == ET_REL;
+
switch (ehdr.e_ident[EI_DATA]) {
case ELFDATA2LSB:
btf__set_endianness(encoder->btf, BTF_LITTLE_ENDIAN);
--
2.31.1
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH dwarves] btf_encoder: Fix handling of percpu symbols on s390
2021-10-12 2:26 [PATCH dwarves] btf_encoder: Fix handling of percpu symbols on s390 Ilya Leoshkevich
@ 2021-10-15 12:54 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 2+ messages in thread
From: Arnaldo Carvalho de Melo @ 2021-10-15 12:54 UTC (permalink / raw)
To: Ilya Leoshkevich
Cc: Arnaldo Carvalho de Melo, dwarves, bpf, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, Heiko Carstens, Vasily Gorbik
Em Tue, Oct 12, 2021 at 04:26:37AM +0200, Ilya Leoshkevich escreveu:
> pahole does not generate VARs for percpu symbols on s390. A percpu
> symbol definition on a typical x86_64 kernel looks like this:
>
> [33] .data..percpu PROGBITS 0000000000000000 01c00000
> ^^^^^^^^^^^^^^^^ sh_addr
> LOAD 0x0000000001c00000 0x0000000000000000 0x000000000286f000
> ^^^^^^^^^^^^^^^^^^ p_vaddr
> 13559: 000000000001ba50 4 OBJECT LOCAL DEFAULT 33 cpu_profile_flip
> ^^^^^^^^^^^^^^^^ st_value
>
> Most importantly, .data..percpu's sh_addr is 0, and this is what pahole
> is currently assuming. However, on s390 this is different:
>
> [37] .data..percpu PROGBITS 00000000019cd000 018ce000
> ^^^^^^^^^^^^^^^^ sh_addr
> LOAD 0x000000000136e000 0x000000000146d000 0x000000000146d000
> ^^^^^^^^^^^^^^^^^^ p_vaddr
> 80377: 0000000001ba1440 4 OBJECT WEAK DEFAULT 37 cpu_profile_flip
> ^^^^^^^^^^^^^^^^ st_value
>
> Fix by restructuring the code to always use section-relative offsets
> for symbols. Change the comment to focus on this invariant.
Thanks, applied.
- Arnaldo
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
> btf_encoder.c | 21 ++++++++++++++-------
> 1 file changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/btf_encoder.c b/btf_encoder.c
> index c341f95..16e90c3 100644
> --- a/btf_encoder.c
> +++ b/btf_encoder.c
> @@ -56,7 +56,8 @@ struct btf_encoder {
> raw_output,
> verbose,
> force,
> - gen_floats;
> + gen_floats,
> + is_rel;
> uint32_t array_index_id;
> struct {
> struct var_info vars[MAX_PERCPU_VAR_CNT];
> @@ -1104,6 +1105,13 @@ static int btf_encoder__collect_percpu_var(struct btf_encoder *encoder, GElf_Sym
> if (encoder->verbose)
> printf("Found per-CPU symbol '%s' at address 0x%" PRIx64 "\n", sym_name, addr);
>
> + /* Make sure addr is section-relative. For kernel modules (which are
> + * ET_REL files) this is already the case. For vmlinux (which is an
> + * ET_EXEC file) we need to subtract the section address.
> + */
> + if (!encoder->is_rel)
> + addr -= encoder->percpu.base_addr;
> +
> if (encoder->percpu.var_cnt == MAX_PERCPU_VAR_CNT) {
> fprintf(stderr, "Reached the limit of per-CPU variables: %d\n",
> MAX_PERCPU_VAR_CNT);
> @@ -1195,12 +1203,9 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder, struct
> addr = var->ip.addr;
> dwarf_name = variable__name(var);
>
> - /* DWARF takes into account .data..percpu section offset
> - * within its segment, which for vmlinux is 0, but for kernel
> - * modules is >0. ELF symbols, on the other hand, don't take
> - * into account these offsets (as they are relative to the
> - * section start), so to match DWARF and ELF symbols we need
> - * to negate the section base address here.
> + /* Make sure addr is section-relative. DWARF, unlike ELF,
> + * always contains virtual symbol addresses, so subtract
> + * the section address unconditionally.
> */
> if (addr < encoder->percpu.base_addr || addr >= encoder->percpu.base_addr + encoder->percpu.sec_sz)
> continue;
> @@ -1322,6 +1327,8 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam
> goto out_delete;
> }
>
> + encoder->is_rel = ehdr.e_type == ET_REL;
> +
> switch (ehdr.e_ident[EI_DATA]) {
> case ELFDATA2LSB:
> btf__set_endianness(encoder->btf, BTF_LITTLE_ENDIAN);
> --
> 2.31.1
--
- Arnaldo
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-10-15 12:54 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-10-12 2:26 [PATCH dwarves] btf_encoder: Fix handling of percpu symbols on s390 Ilya Leoshkevich
2021-10-15 12:54 ` Arnaldo Carvalho de Melo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.