linux/tools/lib/bpf
Andrii Nakryiko 3e6fe5ce4d libbpf: Fix internal USDT address translation logic for shared libraries
Perform the same virtual address to file offset translation that libbpf
is doing for executable ELF binaries also for shared libraries.
Currently libbpf is making a simplifying and sometimes wrong assumption
that for shared libraries relative virtual addresses inside ELF are
always equal to file offsets.

Unfortunately, this is not always the case with LLVM's lld linker, which
now by default generates quite more complicated ELF segments layout.
E.g., for liburandom_read.so from selftests/bpf, here's an excerpt from
readelf output listing ELF segments (a.k.a. program headers):

  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R   0x8
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x0005e4 0x0005e4 R   0x1000
  LOAD           0x0005f0 0x00000000000015f0 0x00000000000015f0 0x000160 0x000160 R E 0x1000
  LOAD           0x000750 0x0000000000002750 0x0000000000002750 0x000210 0x000210 RW  0x1000
  LOAD           0x000960 0x0000000000003960 0x0000000000003960 0x000028 0x000029 RW  0x1000

Compare that to what is generated by GNU ld (or LLVM lld's with extra
-znoseparate-code argument which disables this cleverness in the name of
file size reduction):

  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x000550 0x000550 R   0x1000
  LOAD           0x001000 0x0000000000001000 0x0000000000001000 0x000131 0x000131 R E 0x1000
  LOAD           0x002000 0x0000000000002000 0x0000000000002000 0x0000ac 0x0000ac R   0x1000
  LOAD           0x002dc0 0x0000000000003dc0 0x0000000000003dc0 0x000262 0x000268 RW  0x1000

You can see from the first example above that for executable (Flg == "R E")
PT_LOAD segment (LOAD #2), Offset doesn't match VirtAddr columns.
And it does in the second case (GNU ld output).

This is important because all the addresses, including USDT specs,
operate in a virtual address space, while kernel is expecting file
offsets when performing uprobe attach. So such mismatches have to be
properly taken care of and compensated by libbpf, which is what this
patch is fixing.

Also patch clarifies few function and variable names, as well as updates
comments to reflect this important distinction (virtaddr vs file offset)
and to ephasize that shared libraries are not all that different from
executables in this regard.

This patch also changes selftests/bpf Makefile to force urand_read and
liburand_read.so to be built with Clang and LLVM's lld (and explicitly
request this ELF file size optimization through -znoseparate-code linker
parameter) to validate libbpf logic and ensure regressions don't happen
in the future. I've bundled these selftests changes together with libbpf
changes to keep the above description tied with both libbpf and
selftests changes.

Fixes: 74cc6311ce ("libbpf: Add USDT notes parsing and resolution logic")
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20220616055543.3285835-1-andrii@kernel.org
2022-06-17 01:20:10 +02:00
..
.gitignore libbpf: Make libbpf_version.h non-auto-generated 2021-09-13 15:36:47 -07:00
bpf_core_read.h libbpf: Complete field-based CO-RE helpers with field offset helper 2022-05-09 17:15:32 +02:00
bpf_endian.h libbpf: Make bpf_endian co-exist with vmlinux.h 2020-07-01 09:06:12 +02:00
bpf_gen_internal.h Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next 2021-12-10 15:56:13 -08:00
bpf_helpers.h libbpf: Provide barrier() and barrier_var() in bpf_helpers.h 2022-05-09 17:15:32 +02:00
bpf_prog_linfo.c libbpf: Streamline error reporting for high-level APIs 2021-05-25 17:32:35 -07:00
bpf_tracing.h libbpf: Add ARC support to bpf_tracing.h 2022-04-10 18:53:37 -07:00
bpf.c libbpf: remove bpf_create_map*() APIs 2022-05-19 09:03:31 -07:00
bpf.h libbpf: remove bpf_create_map*() APIs 2022-05-19 09:03:31 -07:00
btf_dump.c libbpf: Add enum64 support for btf_dump 2022-06-07 10:20:43 -07:00
btf.c libbpf: Add enum64 deduplication support 2022-06-07 10:20:43 -07:00
btf.h libbpf: Add enum64 relocation support 2022-06-07 10:20:43 -07:00
Build libbpf: Wire up USDT API and bpf_link integration 2022-04-05 13:16:07 -07:00
gen_loader.c libbpf: Prepare light skeleton for the kernel. 2022-02-10 23:31:51 +01:00
hashmap.c libbpf: Use IS_ERR_OR_NULL() in hashmap__free() 2022-01-12 17:01:36 -08:00
hashmap.h libbpf, hashmap: Fix undefined behavior in hash_bits 2020-11-02 23:33:51 +01:00
libbpf_common.h libbpf: Deprecate bpf_prog_load_xattr() API 2021-12-02 15:23:41 -08:00
libbpf_errno.c libbpf: Streamline error reporting for high-level APIs 2021-05-25 17:32:35 -07:00
libbpf_internal.h libbpf: Add enum64 sanitization 2022-06-07 10:20:43 -07:00
libbpf_legacy.h libbpf: .text routines are subprograms in strict mode 2022-03-17 23:11:15 -07:00
libbpf_probes.c libbpf: Improve LINUX_VERSION_CODE detection 2021-12-28 19:20:31 -08:00
libbpf_version.h libbpf: start 1.0 development cycle 2022-05-19 09:03:31 -07:00
libbpf.c libbpf: Fix an unsigned < 0 bug 2022-06-14 17:01:54 +02:00
libbpf.h libbpf: Fix a couple of typos 2022-06-03 14:53:33 -07:00
libbpf.map libbpf: Add enum64 parsing and new enum64 public API 2022-06-07 10:20:43 -07:00
libbpf.pc.template libbpf: Add zlib as a dependency in pkg-config template 2019-12-16 14:55:29 -08:00
linker.c libbpf: Add enum64 support for bpf linking 2022-06-07 10:20:43 -07:00
Makefile libbpf: fix up global symbol counting logic 2022-05-19 09:03:31 -07:00
netlink.c libbpf: Fix memleak in libbpf_netlink_recv() 2022-02-17 16:09:07 +01:00
nlattr.c libbpf: Switch to void * casting in netlink helpers 2021-06-22 17:04:02 +02:00
nlattr.h libbpf: Switch to void * casting in netlink helpers 2021-06-22 17:04:02 +02:00
relo_core.c libbpf: Add enum64 relocation support 2022-06-07 10:20:43 -07:00
relo_core.h libbpf: Permit 64bit relocation value 2022-06-07 10:20:42 -07:00
ringbuf.c libbpf: Streamline error reporting for high-level APIs 2021-05-25 17:32:35 -07:00
skel_internal.h libbpf: Prepare light skeleton for the kernel. 2022-02-10 23:31:51 +01:00
str_error.c libbpf: Poison kernel-only integer types 2020-01-10 10:38:00 -08:00
str_error.h libbpf: relicense libbpf as LGPL-2.1 OR BSD-2-Clause 2018-10-08 10:09:48 +02:00
strset.c libbpf: Fix memory leak in strset 2021-10-01 22:54:38 +02:00
strset.h libbpf: Extract internal set-of-strings datastructure APIs 2021-03-18 16:14:22 -07:00
usdt.bpf.h libbpf: Use weak hidden modifier for USDT BPF-side API functions 2022-04-08 22:24:15 +02:00
usdt.c libbpf: Fix internal USDT address translation logic for shared libraries 2022-06-17 01:20:10 +02:00
xsk.c libbpf: Fix array_size.cocci warning 2022-03-07 22:13:00 -08:00
xsk.h libbpf: Deprecate AF_XDP support 2021-11-01 18:12:44 -07:00