Re: Question about elf symbol's file offset

2025-03-30 Thread Hengqi Chen
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

2025-03-10 Thread Hengqi Chen
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 ?

2022-12-01 Thread Hengqi Chen via Elfutils-devel
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 ?

2022-12-01 Thread Hengqi Chen via Elfutils-devel
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

2022-12-03 Thread Hengqi Chen via Elfutils-devel
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

2022-12-12 Thread Hengqi Chen via Elfutils-devel
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

2023-04-04 Thread Hengqi Chen via Elfutils-devel
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