Skip to content

libbpf: fix USDT SIB argument handling causing unrecognized register error #9489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: bpf-next_base
Choose a base branch
from

Conversation

kernel-patches-daemon-bpf[bot]
Copy link

Pull request for series with
subject: libbpf: fix USDT SIB argument handling causing unrecognized register error
version: 10
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=991613

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: 0786654
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=991613
version: 10

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: dc0fe95
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=991613
version: 10

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: c80d797
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=991613
version: 10

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: 3ec8560
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=991613
version: 10

…error

On x86-64, USDT arguments can be specified using Scale-Index-Base (SIB)
addressing, e.g. "1@-96(%rbp,%rax,8)". The current USDT implementation
in libbpf cannot parse this format, causing `bpf_program__attach_usdt()`
to fail with -ENOENT (unrecognized register).

This patch fixes this by implementing the necessary changes:
- add correct handling for SIB-addressed arguments in `bpf_usdt_arg`.
- add adaptive support to `__bpf_usdt_arg_type` and
  `__bpf_usdt_arg_spec` to represent SIB addressing parameters.

Signed-off-by: Jiawei Zhao <[email protected]>
…dling logic

When using GCC on x86-64 to compile an usdt prog with -O1 or higher
optimization, the compiler will generate SIB addressing mode for global
array and PC-relative addressing mode for global variable,
e.g. "1@-96(%rbp,%rax,8)" and "-1@4+t1(%rip)".

In this patch:
- add usdt_o2 test case to cover SIB addressing usdt argument spec
  handling logic

Signed-off-by: Jiawei Zhao <[email protected]>
usdt_o2 is intended to exercise the SIB (Scale-Index-Base) argument
handling in libbpf's USDT path. With GCC 13 this reliably produced a
SIB-form argument (e.g. 8@(%rdx,%rax,8)), but with newer GCC (e.g. 15)
the compiler frequently optimizes the probe argument into a plain
register (e.g. 8@%rax) or a stack slot, so the test stops covering the
SIB code path and becomes flaky across toolchains.

Force a SIB memory operand in the probe by:
* placing the base pointer into %rdx and the index into %rax using an
  empty inline asm with output constraints ("=d", "=a") and matching
  inputs
* immediately passing base[idx] to STAP_PROBE1.
* only enable on x86 platform.

This makes the compiler encode the operand as SIB (base + index8),
which in .note.stapsdt shows up as 8@(%rdx,%rax,8) regardless of GCC
version. A memory clobber and noinline prevent reordering/re-allocation
around the probe site.

This change is x86_64-specific and does not alter program semantics; it
only stabilizes the USDT argument shape so the test consistently
validates SIB handling. Clang historically prefers stack temporaries for
such operands, but the selftests build with GCC, and this keeps behavior
stable across GCC versions without introducing a separate .S file.

Signed-off-by: Jiawei Zhao <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant