Re: Question about elf symbol's file offset
Hi Mark, Sorry for the late reply On Wed, Mar 19, 2025 at 8:55 PM Mark Wielaard wrote: > > Hi Hengqi, > > On Tue, 2025-03-11 at 13:27 +0800, Hengqi Chen wrote: > > I want to ask you a question regarding elf internals. > > How to calculate a symbol's file offset (which is kernel uprobe expects) > > in an elf (executable or shared object)? > > Could you point me to a description of what uprobe expects? > I only found this one: https://docs.kernel.org/trace/uprobetracer.html > > Some real world use case use either section header like libbpf: > > > > https://github.com/libbpf/libbpf/blob/374036c9f1cdfe2a8df98d9d6a53c34fd02de14b/src/elf.c#L259-L270 > > Or use program header like BCC: > > > > https://github.com/iovisor/bcc/blob/82f9d1cb633aa3b4ebcbbc5d8b809f48d3dfa222/src/cc/bcc_syms.cc#L767-L775 > > > > Which is correct ? Is there a unified way to get the file offset of a > > symbol ? > > I am not sure I understand enough of what uprobe expects to know right > now. In general it depends on the ELF file type, for ET_REL files the > st_value is relative to to associated section (unless SHN_ABS), > otherwise the associated section load address doesn't really matter > except for where the program header says it is loaded, which might be > absolute (for ET_EXEC) or dynamic (for ET_DYN). It might also depend on > whether the dynamic loader has relocated the symbol and/or section > addresses (so whether you are reading the values from memory or on > disk). > >From the link above, it seems like the linux kernel expects values reading from disk (using objdump). The binary provided here ([0]), contains the following symbol: _ZN7cluster15topics_frontend13create_topicsE17fragmented_vectorINS_37custom_assignable_topic_configurationELm18446744073709551615EENSt3__16chrono10time_pointIN7seastar12lowres_clockENS5_8durationIxNS4_5ratioILl1ELl10EEE The symbol points to section #13, which is .eh_frame_hdr. But value (virtual address) 081658d0 actually belongs to section #15 (.text): [15] .text PROGBITS035e0700 35df700 7a9de55 00 AX 0 0 64 [0]: https://github.com/libbpf/libbpf-rs/issues/1110#issuecomment-2699221802 This results in different offsets calculated from section header and program header. > Cheers, > > Mark
Question about elf symbol's file offset
Hi Mark, I want to ask you a question regarding elf internals. How to calculate a symbol's file offset (which is kernel uprobe expects) in an elf (executable or shared object)? Some real world use case use either section header like libbpf: https://github.com/libbpf/libbpf/blob/374036c9f1cdfe2a8df98d9d6a53c34fd02de14b/src/elf.c#L259-L270 Or use program header like BCC: https://github.com/iovisor/bcc/blob/82f9d1cb633aa3b4ebcbbc5d8b809f48d3dfa222/src/cc/bcc_syms.cc#L767-L775 Which is correct ? Is there a unified way to get the file offset of a symbol ? Thanks. -- Hengqi
dwarf_nextcu can't handle abbrev offset correctly ?
Hi, I am using pahole (which relies on libelf) to process an elf file ([0]): LLVM_OBJCOPY="objcopy" pahole -J --btf_gen_floats --btf_base vmlinux adl_pci9111.ko This failed with: die__process: DW_TAG_compile_unit, DW_TAG_type_unit, DW_TAG_partial_unit or DW_TAG_skeleton_unit expected got member (0xd)! The .ko contains two CU, readelf says that the abbrev offsets are at 0 and 0x907, but dwarf_nextcu reports that abbrev offsets are both at 0. pahole expects to find DW_TAG_compile_unit, but seams that the wrong abbrev offset causes the failure. [0]: https://gitlab.com/chenhengqi/loong-debug -- Hengqi
Re: dwarf_nextcu can't handle abbrev offset correctly ?
Hi Mark, On 2022/12/1 23:54, Mark Wielaard wrote: > Hi Hengqi, > > On Thu, 2022-12-01 at 23:34 +0800, Hengqi Chen via Elfutils-devel > wrote: >> I am using pahole (which relies on libelf) to process an elf file >> ([0]): >> >> LLVM_OBJCOPY="objcopy" pahole -J --btf_gen_floats --btf_base >> vmlinux adl_pci9111.ko >> >> This failed with: >> >> die__process: DW_TAG_compile_unit, DW_TAG_type_unit, >> DW_TAG_partial_unit or DW_TAG_skeleton_unit expected got member >> (0xd)! >> >> The .ko contains two CU, readelf says that the abbrev offsets are at >> 0 and 0x907, >> but dwarf_nextcu reports that abbrev offsets are both at 0. >> >> pahole expects to find DW_TAG_compile_unit, but seams that the wrong >> abbrev offset causes the failure. >> >> >> [0]: https://gitlab.com/chenhengqi/loong-debug > > I took a quick look at the adl_pci9111.ko there. And the issue is that > elfutils doesn't know how to handle the relocations for LoongArch yet. > > Specifically the backend should implement the reloc_simple_type hook. > > Cheers, > > Mark That's great. Thanks for the pointer. Will try to implement it. Cheers, --- Hengqi
[PATCH] Add support for LoongArch
This implements initial support for the LoongArch architecture. Signed-off-by: Hengqi Chen --- backends/ChangeLog | 7 backends/Makefile.am | 7 +++- backends/loongarch_init.c| 50 ++ backends/loongarch_reloc.def | 81 backends/loongarch_symbol.c | 74 libebl/ChangeLog | 4 ++ libebl/eblopenbackend.c | 2 + src/ChangeLog| 4 ++ src/elflint.c| 2 +- 9 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 backends/loongarch_init.c create mode 100644 backends/loongarch_reloc.def create mode 100644 backends/loongarch_symbol.c diff --git a/backends/ChangeLog b/backends/ChangeLog index 5b0daffe..5813ddcc 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,10 @@ +2022-12-02 Hengqi Chen + + * Makefile.am (modules): Add loongarch. + * loongarch_init.c: New file. + * loongarch_reloc.def: New file. + * loongarch_symbol.c: New file. + 2022-08-09 Andreas Schwab * riscv_init.c (riscv_init): HOOK segment_type_name, diff --git a/backends/Makefile.am b/backends/Makefile.am index 9566377f..0824123d 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -37,7 +37,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \ noinst_LIBRARIES = libebl_backends.a libebl_backends_pic.a modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \ - m68k bpf riscv csky + m68k bpf riscv csky loongarch i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \ i386_retval.c i386_regs.c i386_auxv.c \ @@ -96,11 +96,14 @@ riscv_SRCS = riscv_init.c riscv_symbol.c riscv_cfi.c riscv_regs.c \ csky_SRCS = csky_attrs.c csky_init.c csky_symbol.c csky_cfi.c \ csky_regs.c csky_initreg.c csky_corenote.c +loongarch_SRCS = loongarch_init.c loongarch_symbol.c + libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \ $(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \ $(aarch64_SRCS) $(sparc_SRCS) $(ppc_SRCS) \ $(ppc64_SRCS) $(s390_SRCS) \ - $(m68k_SRCS) $(bpf_SRCS) $(riscv_SRCS) $(csky_SRCS) + $(m68k_SRCS) $(bpf_SRCS) $(riscv_SRCS) $(csky_SRCS) \ + $(loongarch_SRCS) libebl_backends_pic_a_SOURCES = am_libebl_backends_pic_a_OBJECTS = $(libebl_backends_a_SOURCES:.c=.os) diff --git a/backends/loongarch_init.c b/backends/loongarch_init.c new file mode 100644 index ..a8ed9e81 --- /dev/null +++ b/backends/loongarch_init.c @@ -0,0 +1,50 @@ +/* Initialization of LoongArch specific backend library. + Copyright (C) 2022 Hengqi Chen + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKENDloongarch_ +#define RELOC_PREFIX R_LARCH_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on loongarch_reloc.def. */ +#include "common-reloc.c" + + +Ebl * +loongarch_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh) +{ + loongarch_init_reloc (eh); + HOOK (eh, reloc_simple_type); + + return eh; +} diff --git a/backends/loongarch_reloc.def b/backends/loongarch_reloc.def new file mode 100644 index ..dd4a6b6d --- /dev/null +++ b/backends/loongarch_reloc.def @@ -0,0 +1,81 @@ +/* List the relocation types for LoongArch. -*- C -*- + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundatio
Re: [PATCH] Add support for LoongArch
Hi, Mark: Any comments? Thanks. With this patch, pahole is now able to convert dwarf to BTF on LoongArch machine. cheers, -- Hengqi On Sat, Dec 3, 2022 at 9:47 PM Hengqi Chen wrote: > > This implements initial support for the LoongArch architecture. > > Signed-off-by: Hengqi Chen > --- > backends/ChangeLog | 7 > backends/Makefile.am | 7 +++- > backends/loongarch_init.c| 50 ++ > backends/loongarch_reloc.def | 81 > backends/loongarch_symbol.c | 74 > libebl/ChangeLog | 4 ++ > libebl/eblopenbackend.c | 2 + > src/ChangeLog| 4 ++ > src/elflint.c| 2 +- > 9 files changed, 228 insertions(+), 3 deletions(-) > create mode 100644 backends/loongarch_init.c > create mode 100644 backends/loongarch_reloc.def > create mode 100644 backends/loongarch_symbol.c > > diff --git a/backends/ChangeLog b/backends/ChangeLog > index 5b0daffe..5813ddcc 100644 > --- a/backends/ChangeLog > +++ b/backends/ChangeLog > @@ -1,3 +1,10 @@ > +2022-12-02 Hengqi Chen > + > + * Makefile.am (modules): Add loongarch. > + * loongarch_init.c: New file. > + * loongarch_reloc.def: New file. > + * loongarch_symbol.c: New file. > + > 2022-08-09 Andreas Schwab > > * riscv_init.c (riscv_init): HOOK segment_type_name, > diff --git a/backends/Makefile.am b/backends/Makefile.am > index 9566377f..0824123d 100644 > --- a/backends/Makefile.am > +++ b/backends/Makefile.am > @@ -37,7 +37,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/libebl > -I$(top_srcdir)/libasm \ > noinst_LIBRARIES = libebl_backends.a libebl_backends_pic.a > > modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \ > - m68k bpf riscv csky > + m68k bpf riscv csky loongarch > > i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \ > i386_retval.c i386_regs.c i386_auxv.c \ > @@ -96,11 +96,14 @@ riscv_SRCS = riscv_init.c riscv_symbol.c riscv_cfi.c > riscv_regs.c \ > csky_SRCS = csky_attrs.c csky_init.c csky_symbol.c csky_cfi.c \ > csky_regs.c csky_initreg.c csky_corenote.c > > +loongarch_SRCS = loongarch_init.c loongarch_symbol.c > + > libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \ > $(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \ > $(aarch64_SRCS) $(sparc_SRCS) $(ppc_SRCS) \ > $(ppc64_SRCS) $(s390_SRCS) \ > - $(m68k_SRCS) $(bpf_SRCS) $(riscv_SRCS) > $(csky_SRCS) > + $(m68k_SRCS) $(bpf_SRCS) $(riscv_SRCS) > $(csky_SRCS) \ > + $(loongarch_SRCS) > > libebl_backends_pic_a_SOURCES = > am_libebl_backends_pic_a_OBJECTS = $(libebl_backends_a_SOURCES:.c=.os) > diff --git a/backends/loongarch_init.c b/backends/loongarch_init.c > new file mode 100644 > index ..a8ed9e81 > --- /dev/null > +++ b/backends/loongarch_init.c > @@ -0,0 +1,50 @@ > +/* Initialization of LoongArch specific backend library. > + Copyright (C) 2022 Hengqi Chen > + This file is part of elfutils. > + > + This file is free software; you can redistribute it and/or modify > + it under the terms of either > + > + * the GNU Lesser General Public License as published by the Free > + Software Foundation; either version 3 of the License, or (at > + your option) any later version > + > + or > + > + * the GNU General Public License as published by the Free > + Software Foundation; either version 2 of the License, or (at > + your option) any later version > + > + or both in parallel, as here. > + > + elfutils is distributed in the hope that it will be useful, but > + WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + General Public License for more details. > + > + You should have received copies of the GNU General Public License and > + the GNU Lesser General Public License along with this program. If > + not, see <http://www.gnu.org/licenses/>. */ > + > +#ifdef HAVE_CONFIG_H > +# include > +#endif > + > +#define BACKENDloongarch_ > +#define RELOC_PREFIX R_LARCH_ > +#include "libebl_CPU.h" > + > +/* This defines the common reloc hooks based on loongarch_reloc.def. */ > +#include "common-reloc.c" > + > + > +Ebl * > +loongarch_init (Elf *elf __attribute__ ((unused)), > + GElf_Half machine __attribute__ ((unused)), > +
Re: [PATCH] backends: add checks for _GLOBAL_OFFSET_TABLE_ on loongarch
Hi, Youling On Sat, Apr 1, 2023 at 11:19 AM Youling Tang wrote: > > Add handling of _GLOBAL_OFFSET_TABLE_. > > Before applying the patch: > $ ./src/elflint --gnu-ld ./src/elflint > section [35] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0x68548 > does not match .got.plt section address 0x68238 > > After applying the patch: > $ ./src/elflint --gnu-ld ./src/elflint > No errors > > Signed-off-by: Liwei Ge > Signed-off-by: Youling Tang > --- > backends/ChangeLog | 4 > backends/loongarch_init.c | 1 + > backends/loongarch_symbol.c | 35 +++ > 3 files changed, 40 insertions(+) > > diff --git a/backends/ChangeLog b/backends/ChangeLog > index 81f08314..41071953 100644 > --- a/backends/ChangeLog > +++ b/backends/ChangeLog > @@ -1,3 +1,7 @@ > +2023-04-01 Youling Tang > + * loongarch_init.c (loongarch_init): Hook check_special_symbol. > + * loongarch_symbol.c (loongarch_check_special_symbol): New function. > + > 2023-02-07 Mark Wielaard > > * libebl_CPU.h (dwarf_peeled_die_type): Explicitly handle > diff --git a/backends/loongarch_init.c b/backends/loongarch_init.c > index 59d8cc3d..b641b07f 100644 > --- a/backends/loongarch_init.c > +++ b/backends/loongarch_init.c > @@ -46,6 +46,7 @@ loongarch_init (Elf *elf __attribute__ ((unused)), >loongarch_init_reloc (eh); >HOOK (eh, reloc_simple_type); >HOOK (eh, machine_flag_check); > + HOOK (eh, check_special_symbol); > >return eh; > } > diff --git a/backends/loongarch_symbol.c b/backends/loongarch_symbol.c > index 43306ab8..5ce55bad 100644 > --- a/backends/loongarch_symbol.c > +++ b/backends/loongarch_symbol.c > @@ -79,3 +79,38 @@ loongarch_machine_flag_check (GElf_Word flags) >return ((flags &~ (EF_LARCH_ABI_MODIFIER_MASK > | EF_LARCH_OBJABI_V1)) == 0); > } > + > +/* Check whether given symbol's st_value and st_size are OK despite failing > + normal checks. */ > +bool > +loongarch_check_special_symbol (Elf *elf, const GElf_Sym *sym, > + const char *name, const GElf_Shdr *destshdr) > +{ > + if (name != NULL > + && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) > +{ > + size_t shstrndx; > + if (elf_getshdrstrndx (elf, &shstrndx) != 0) > + return false; > + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); > + if (sname != NULL > + && (strcmp (sname, ".got") == 0 || strcmp (sname, ".got.plt") == 0)) > + { > + Elf_Scn *scn = NULL; > + while ((scn = elf_nextscn (elf, scn)) != NULL) > + { > + GElf_Shdr shdr_mem; > + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); > + if (shdr != NULL) > + { > + sname = elf_strptr (elf, shstrndx, shdr->sh_name); > + if (sname != NULL && strcmp (sname, ".got") == 0) > + return (sym->st_value >= shdr->sh_addr > + && sym->st_value < shdr->sh_addr + shdr->sh_size); > + } > + } > + } > +} > + > + return false; > +} > -- > 2.37.1 > I've tested this locally, but still remains one error: section [34] '.symtab': _DYNAMIC symbol size 0 does not match dynamic segment size 480 Cheers, --- Hengqi