iovisor / iovisor/bcc

RFC: Support fully static libbpf-tools builds for Android/AArch64 deployment

Open
#5,548 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
22.7k
Forks
4.1k
Avg merge
5d 13h
Merged PRs (30d)
3

Description

## Summary

BCC's `libbpf-tools` currently links `libbpf` statically, but normally leaves
system libraries such as libc, libelf, and zlib dynamically linked. This works
well on conventional Linux distributions, but it is not directly suitable for
Android devices, where the expected GNU/Linux shared libraries are generally
unavailable or incompatible.

This RFC proposes an optional AArch64 cross-build environment that builds the
required user-space libraries from source and produces fully static
`libbpf-tools` executables for deployment on Android devices.

The proposal is limited to the build and deployment workflow. It does not
require changes to the functional source code of individual libbpf tools or
their BPF programs.

## Motivation

Android devices do not normally provide compatible versions of libraries such
as `libelf.so.1`, `libz.so`, or other GNU/Linux user-space dependencies needed
by dynamically linked `libbpf-tools` binaries. Packaging those shared
libraries with every tool also requires target-side library-path management
and introduces additional compatibility problems.

Fully static executables avoid those runtime shared-library dependencies. A
tool can be copied to the device with `adb push` and executed directly,
subject to the device's kernel configuration, BTF availability, SELinux
policy, and privileges.

## Proposed build support

The proposed build environment would:

1. use an AArch64 GNU/Linux cross compiler;
2. build all required user-space dependencies from pinned source revisions;
3. link libc, libelf, zlib, libzstd, liblzma, and libbpf statically as needed;
4. preserve the existing native and partially static build as the default;
5. provide an explicit, opt-in target or build script for fully static tools;
6. use `-j3` for all compilation stages;
7. audit generated ELF files to ensure that they contain no dynamic section,
interpreter, or `DT_NEEDED` entries; and
8. optionally stage the binaries for deployment with `adb push`.

The intended interface could be a dedicated make target or a wrapper script,
for example:

```sh
./scripts/build-static-aarch64.sh -j3
```

The exact interface can be adjusted to match BCC project conventions.

## Source-code impact

The prototype does not require modifications to the C source code of existing
`libbpf-tools` or to their BPF programs. Cross-build-specific behavior is kept
in external build scripts, Makefile options, dependency configuration, ELF
auditing, and deployment helpers.

The normal build remains unchanged. Fully static AArch64 output is enabled
only when explicitly requested.

All required libraries are built from source. In particular, `libelf.a` is
linked into the resulting executables, so the Android device does not need
`libelf.so.1`.

## Prototype and Android validation

The approach has been prototyped successfully. Multiple AArch64
`libbpf-tools`, including `biosnoop`, `capable`, and `execsnoop`, were built as
fully static executables and tested on an Android AArch64 device through
`adb shell`.

Example deployment:

```sh
adb push biosnoop /data/local/tmp/biosnoop
adb shell chmod 755 /data/local/tmp/biosnoop
adb shell /data/local/tmp/biosnoop

TIME(s) COMM PID DISK T SECTOR BYTES LAT(ms)
0.000000 POSIX timer 0 1206 sda WS 115717800 4096 0.153
0.000237 POSIX timer 0 1206 sda WS 144686432 4096 0.024
0.055405 kworker/0:3 1667 sda N -1 0 0.408
0.255093 dbthread 8623 sda WS 115718616 4096 0.130
0.255182 dbthread 8623 sda WS 115718624 4096 0.203
0.255192 dbthread 8623 sda WS 115718632 8192 0.207
0.255626 dbthread 8623 sda WS 144686440 4096 0.024
0.255913 ? 0 sda FF -1 0 0.119
0.256035 dbthread 8623 sda WS 144686448 4096 0.044
0.256207 ? 0 sda FF -1 0 0.105
0.317385 kworker/0:3 1667 sda N -1 0 0.417
0.474849 SettingsProvid 3532 sda WS 115718648 81920 0.216
0.475058 SettingsProvid 3532 sda WS 144686456 4096 0.027
0.535385 kworker/0:3 1667 sda N -1 0 0.410
0.770098 touch-main-loo 2349 sda R 8517944 4096 0.198
0.770364 touch-main-loo 2349 sda RA 8431168 4096 0.075
0.770469 touch-main-loo 2349 sda RA 8431176 8192 0.083
```

The ELF audit produces:

```sh
$ readelf -d biosnoop

There is no dynamic section in this file.
```

Therefore, the deployed tool does not require `libelf.so.1`, `libz.so`, or
other build-specific shared libraries on the device.

## Platform scope

The current prototype uses an AArch64 GNU/Linux/glibc cross toolchain and runs
the resulting fully static binaries on Android. This is an Android deployment
workflow, not a native Android NDK/bionic build.

AArch64 GNU/Linux/glibc and Android NDK/bionic are different targets and
should not be treated as interchangeable. Native NDK/bionic support, if
desired, should be considered separately.

Successful execution also depends on target-specific conditions, including:

- a kernel with the required eBPF features;
- suitable BTF data for CO-RE relocation;
- root or the required Linux capabilities;
- compatible SELinux policy; and
- tracepoints, kprobes, and kernel symbols required by each tool.

## Questions

1. Is an optional fully static AArch64 build mode appropriate for BCC
`libbpf-tools`?
2. Should the implementation be integrated into the existing Makefile or kept
in a separate build script?
3. Should the project validate fully static output in CI by checking for
`PT_INTERP`, `DT_NEEDED`, and dynamic sections?
4. Should Android deployment documentation explicitly distinguish this
GNU/Linux/glibc approach from native Android NDK/bionic support?

The prototype demonstrates that fully static `libbpf-tools` provide a simple
and practical deployment path for Android AArch64 devices without changing
the tools' functional source code.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the existing Makefile and build scripts; the proposed entry point is scripts/build-static-aarch64.sh, though the issue leaves the final interface open. Compare the native and partially static build paths, then define how dependency builds, ELF checks with readelf, and optional adb deployment should fit BCC conventions. Done means an opt-in AArch64 workflow produces validated fully static libbpf-tools without changing the default build.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, c, linux, shell
Domain
build-system, mobile-dev, operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.