• Home
Name Date Size #Lines LOC

..--

apex/04-Jul-2025-418368

benchmarks/05-Jul-2025-577,920575,234

build/04-Jul-2025-333261

cpu_target_features/04-Jul-2025-165120

docs/04-Jul-2025-4,1163,269

libc/04-Jul-2025-315,956235,165

libdl/04-Jul-2025-808555

libfdtrack/04-Jul-2025-546397

libm/04-Jul-2025-28,45916,947

libstdc++/04-Jul-2025-6550

linker/04-Jul-2025-18,91312,189

tests/04-Jul-2025-301,901281,242

tools/04-Jul-2025-6851

.clang-formatD04-Jul-2025239

.gitignoreD04-Jul-202511 32

CPPLINT.cfgD04-Jul-202575 32

CleanSpec.mkD04-Jul-20253 KiB688

OWNERSD04-Jul-2025174 107

PREUPLOAD.cfgD04-Jul-2025190 96

README.mdD04-Jul-202521 KiB504374

TEST_MAPPINGD04-Jul-20251.7 KiB108107

android-changes-for-ndk-developers.mdD04-Jul-202524.7 KiB547414

README.md

1# bionic maintainer overview
2
3[bionic](https://en.wikipedia.org/wiki/Bionic_(software)) is Android's
4C library, math library, and dynamic linker.
5
6This document is a high-level overview of making changes to bionic itself.
7If you're trying to _use_ bionic, or want more in-depth information about
8some part of the implementation, see [all the bionic documentation](docs/).
9
10## What are the big pieces of bionic?
11
12#### libc/ --- libc.so, libc.a
13
14The C library. Stuff like `fopen(3)` and `kill(2)`.
15
16#### libm/ --- libm.so, libm.a
17
18The math library. Traditionally Unix systems kept stuff like `sin(3)` and
19`cos(3)` in a separate library to save space in the days before shared
20libraries.
21
22#### libdl/ --- libdl.so
23
24The dynamic linker interface library. This is actually just a bunch of stubs
25that the dynamic linker replaces with pointers to its own implementation at
26runtime. This is where stuff like `dlopen(3)` lives.
27
28#### libstdc++/ --- libstdc++.so
29
30The C++ ABI support functions. The C++ compiler doesn't know how to implement
31thread-safe static initialization and the like, so it just calls functions that
32are supplied by the system. Stuff like `__cxa_guard_acquire` and
33`__cxa_pure_virtual` live here.
34
35#### linker/ --- /system/bin/linker and /system/bin/linker64
36
37The dynamic linker. When you run a dynamically-linked executable, its ELF file
38has a `DT_INTERP` entry that says "use the following program to start me".  On
39Android, that's either `linker` or `linker64` (depending on whether it's a
4032-bit or 64-bit executable). It's responsible for loading the ELF executable
41into memory and resolving references to symbols (so that when your code tries to
42jump to `fopen(3)`, say, it lands in the right place).
43
44#### tests/ --- unit tests
45
46The `tests/` directory contains unit tests. Roughly arranged as one file per
47publicly-exported header file. `tests/headers/` contains compile-only tests
48that just check that things are _in_ the headers, whereas the "real" tests
49check actual _behavior_.
50
51#### benchmarks/ --- benchmarks
52
53The `benchmarks/` directory contains benchmarks, with its own [documentation](benchmarks/README.md).
54
55
56## What's in libc/?
57
58```
59libc/
60  arch-arm/
61  arch-arm64/
62  arch-common/
63  arch-x86/
64  arch-x86_64/
65    # Each architecture has its own subdirectory for stuff that isn't shared
66    # because it's architecture-specific. There will be a .mk file in here that
67    # drags in all the architecture-specific files.
68    bionic/
69      # Every architecture needs a handful of machine-specific assembler files.
70      # They live here.
71    string/
72      # Most architectures have a handful of optional assembler files
73      # implementing optimized versions of various routines. The <string.h>
74      # functions are particular favorites.
75    syscalls/
76      # The syscalls directories contain script-generated assembler files.
77      # See 'Adding system calls' later.
78
79  include/
80    # The public header files on everyone's include path. These are a mixture of
81    # files written by us and files taken from BSD.
82
83  kernel/
84    # The kernel uapi header files. The "libc" headers that developers actually
85    # use are a mixture of headers provided by the C library itself (which,
86    # for bionic, are in bionic/libc/include/) and headers provided by the
87    # kernel. This is because ISO C and POSIX will say things like "there is
88    # a constant called PROT_NONE" or "there is a type called struct stat,
89    # and it contains a field called st_size", but they won't necessarily say
90    # what _value_ that constant has, or what _order_ the fields in a type
91    # are in. Those are left to individual kernels' ABIs. In an effort to --
92    # amongst other things, see https://lwn.net/Articles/507794/ for more
93    # background -- reduce copy & paste, the Linux kernel makes all the types
94    # and constants that make up the "userspace API" (uapi) available as
95    # headers separate from their internal-use headers (which contain all kinds
96    # of extra stuff that isn't available to userspace). We import the latest
97    # released kernel's uapi headers in external/kernel-headers/, but we don't
98    # use those headers directly in bionic. The bionic/libc/kernel/ directory
99    # contains scrubbed copies of the originals from external/kernel-headers/.
100    # The generate_uapi_headers.sh script should be used to go from a kernel
101    # tree to external/kernel-headers/ --- this takes care of the
102    # architecture-specific details. The update_all.py script should then be
103    # used to regenerate bionic's copy from external/kernel-headers/.
104    # The files in bionic must not be edited directly because any local changes
105    # will be overwritten by the next update. "Updating kernel header files"
106    # below has more information on this process.
107
108  private/
109    # These are private header files meant for use within bionic itself.
110
111  dns/
112    # Contains the DNS resolver (originates from NetBSD code).
113
114  upstream-freebsd/
115  upstream-netbsd/
116  upstream-openbsd/
117    # These directories contain upstream source with no local changes.
118    # Any time we can just use a BSD implementation of something unmodified,
119    # we should. Ideally these should probably have been three separate git
120    # projects in external/, but they're here instead mostly by historical
121    # accident (because it wouldn't have been easy to import just the tiny
122    # subset of these operating systems that -- unlike Android -- just have
123    # one huge repository rather than lots of little ones and a mechanism
124    # like our `repo` tool).
125    # The structure under these directories mimics the relevant upstream tree,
126    # but in order to actually be able to compile this code in our tree
127    # _without_ making modifications to the source files directly, we also
128    # have the following subdirectories in each one that aren't upstream:
129    android/
130      include/
131        # This is where we keep the hacks necessary to build BSD source
132        # in our world. The *-compat.h files are automatically included
133        # using -include, but we also provide equivalents for missing
134        # header/source files needed by the BSD implementation.
135
136  bionic/
137    # This is the biggest mess. The C++ files are files we own, typically
138    # because the Linux kernel interface is sufficiently different that we
139    # can't use any of the BSD implementations. The C files are usually
140    # legacy mess that needs to be sorted out, either by replacing it with
141    # current upstream source in one of the upstream directories or by
142    # switching the file to C++ and cleaning it up.
143
144  malloc_debug/
145    # The code that implements the functionality to enable debugging of
146    # native allocation problems.
147
148  stdio/
149    # These are legacy files of dubious provenance. We're working to clean
150    # this mess up, and this directory should disappear.
151
152  tools/
153    # Various tools used to maintain bionic.
154
155  tzcode/
156    # A modified superset of the IANA tzcode. Most of the modifications relate
157    # to Android's use of a single file (with corresponding index) to contain
158    # timezone data.
159  zoneinfo/
160    # Android-format timezone data.
161    # See 'Updating tzdata' later.
162```
163
164
165## Adding libc wrappers for system calls
166
167The first question you should ask is "should I add a libc wrapper for
168this system call?". The answer is usually "no".
169
170The answer is "yes" if the system call is part of the POSIX standard.
171
172The answer is probably "yes" if the system call has a wrapper in at
173least one other C library (typically glibc/musl or Apple's libc).
174
175The answer may be "yes" if the system call has three/four distinct
176users in different projects, and there isn't a more specific higher-level
177library that would make more sense as the place to add the wrapper.
178
179In all other cases, you should use
180[syscall(3)](https://man7.org/linux/man-pages/man2/syscall.2.html) instead.
181
182Adding a system call usually involves:
183
184  1. Add an entry (or entries, in some cases) to SYSCALLS.TXT.
185     See SYSCALLS.TXT itself for documentation on the format.
186     See also the notes below for how to deal with tricky cases like `off_t`.
187  2. Find the right header file to work in by looking up your system call
188     on [man7.org](https://man7.org/linux/man-pages/dir_section_2.html).
189     (If there's no header file given, see the points above about whether we
190     should really be adding this or not!)
191  3. Add constants (and perhaps types) to the appropriate header file.
192     Note that you should check to see whether the constants are already in
193     kernel uapi header files, in which case you just need to make sure that
194     the appropriate header file in libc/include/ `#include`s the relevant
195     `linux/` file or files.
196  4. Add function declarations to the appropriate header file. Don't forget
197     to include the appropriate `__INTRODUCED_IN()`, with the right API level
198     for the first release your system call wrapper will be in. See
199     libc/include/android/api_level.h for the API levels.
200     If the header file doesn't exist, copy all of libc/include/sys/sysinfo.h
201     into your new file --- it's a good short example to start from.
202
203     Note also our style for naming arguments: always use two leading
204     underscores (so developers are free to use any of the unadorned names as
205     macros without breaking things), avoid abbreviations, and ideally try to
206     use the same name as an existing system call (to reduce the amount of
207     English vocabulary required by people who just want to use the function
208     signatures). If there's a similar function already in the C library,
209     check what names it's used. Finally, prefer the `void*` orthography we
210     use over the `void *` you'll see on man7.org.)
211  5. Add basic documentation to the header file. Again, the existing
212     libc/include/sys/sysinfo.h is a good short example that shows the
213     expected style.
214
215     Most of the detail should actually be left to the man7.org page, with
216     only a brief one-sentence explanation (usually based on the description
217     in the NAME section of the man page) in our documentation. Always
218     include the return value/error reporting details (you can find out
219     what the system call returns from the RETURN VALUE of the man page),
220     but try to match the wording and style wording from _our_ existing
221     documentation; we're trying to minimize the amount of English readers
222     need to understand by using the exact same wording where possible).
223     Explicitly say which version of Android the function was added to in
224     the documentation because the documentation generation tool doesn't yet
225     understand `__INTRODUCED_IN()`.
226
227     Explicitly call out any Android-specific changes/additions/limitations
228     because they won't be on the man7.org page.
229  6. Add the function name to the correct section in libc/libc.map.txt; it'll
230     be near the end of the file. You may need to add a new section if you're
231     the first to add a system call to this version of Android.
232  7. Add a basic test. Don't try to test everything; concentrate on just testing
233     the code that's actually in *bionic*, not all the functionality that's
234     implemented in the kernel. For simple syscalls, that's just the
235     auto-generated argument and return value marshalling.
236
237     Add a test in the right file in tests/. We have one file per header, so if
238     your system call is exposed in <unistd.h>, for example, your test would go
239     in tests/unistd_test.cpp.
240
241     A trivial test that deliberately supplies an invalid argument helps check
242     that we're generating the right symbol and have the right declaration in
243     the header file, and that the change to libc.map.txt from step 5 is
244     correct. (You can use strace(1) manually to confirm that the correct
245     system call is being made.)
246
247     For testing the *kernel* side of things, we should prefer to rely on
248     https://github.com/linux-test-project/ltp for kernel testing, but you'll
249     want to check that external/ltp does contain tests for the syscall you're
250     adding. Also check that external/ltp is using the libc wrapper for the
251     syscall rather than calling it "directly" via syscall(3)!
252
253Some system calls are harder than others. The most common problem is a 64-bit
254argument such as `off64_t` (a *pointer* to a 64-bit argument is fine, since
255pointers are always the "natural" size for the architecture regardless of the
256size of the thing they point to). Whenever you have a function that takes
257`off_t` or `off64_t`, you'll need to consider whether you actually need a foo()
258and a foo64(), and whether they will use the same underlying system call or are
259implemented as two different system calls. It's usually easiest to find a
260similar system call and copy and paste from that. You'll definitely need to test
261both on 32-bit and 64-bit. (These special cases warrant more testing than the
262easy cases, even if only manual testing with strace. Sadly it isn't always
263feasible to write a working test for the interesting cases -- offsets larger
264than 2GiB, say -- so you may end up just writing a "meaningless" program whose
265only purpose is to give you patterns to look for when run under strace(1).)
266
267A general example of adding a system call:
268https://android-review.googlesource.com/c/platform/bionic/+/2073827
269
270### Debugging tips
271
272If a test fails to build with an undefined symbol error,
273this is most likely the _host_ reference test against glibc,
274and you need to add an `#if defined(__GLIBC__)` to the test.
275(Search for existing examples to copy & paste,
276in particular to make sure you include the `GTEST_SKIP()`.)
277
278When we switch to musl for the host libc, this should be less of a problem.
279
280## Updating kernel header files
281
282As mentioned above, this is currently a two-step process:
283
284  1. Use generate_uapi_headers.sh to go from a Linux source tree to appropriate
285     contents for external/kernel-headers/.
286  2. Run update_all.py to scrub those headers and import them into bionic.
287
288Note that if you're actually just trying to expose device-specific headers to
289build your device drivers, you shouldn't modify bionic. Instead use
290`TARGET_DEVICE_KERNEL_HEADERS` and friends described in [config.mk](https://android.googlesource.com/platform/build/+/main/core/config.mk#186).
291
292
293## Updating tzdata
294
295Tzdata updates are now handled by the libcore team because it needs to be
296updated in sync with icu's copy of the data, and they own that.
297
298See
299[system/timezone/README.android](https://android.googlesource.com/platform/system/timezone/+/main/README.android)
300for more information.
301
302
303## Verifying changes
304
305If you make a change that is likely to have a wide effect on the tree (such as a
306libc header change), you should run `make checkbuild`. A regular `make` will
307_not_ build the entire tree; just the minimum number of projects that are
308required for the device. Tests, additional developer tools, and various other
309modules will not be built. Note that `make checkbuild` will not be complete
310either, as `make tests` covers a few additional modules, but generally speaking
311`make checkbuild` is enough.
312
313
314## Running the tests
315
316The tests are all built from the tests/ directory. There is a separate
317directory `benchmarks/` containing benchmarks, and that has its own
318documentation on [running the benchmarks](benchmarks/README.md).
319
320### Building
321
322We assume you've already checked out the Android source tree.
323
324To build, make sure you're in the right directory and you've set up your environment:
325
326    $ cd main  # Or whatever you called your Android source tree.
327    $ source build/envsetup.sh
328
329Then choose an appropriate "lunch". If you're not testing on a device,
330two choices are particularly useful.
331
332If you want to be able to run tests and benchmarks directly on your x86-64
333host machine, use:
334
335    $ lunch aosp_cf_x86_64_phone-trunk_staging-userdebug
336
337Alternatively, if you want to (say) check generated arm64 code without having
338a specific device in mind, use:
339
340    $ lunch aosp_cf_arm64_phone-trunk_staging-userdebug
341
342Note that in both cases,
343these targets will also build the corresponding 32-bit variant.
344See below for where the 64-bit and 32-bit files end up.
345
346See [Build Android](https://source.android.com/docs/setup/build/building)
347for more details.
348
349### Device tests
350
351Once you've completed that setup, you can build:
352
353    $ cd bionic
354    $ mm
355
356This will build everything: bionic, the benchmarks, and the tests
357(and all the dependencies).
358
359If you want to test on a device,
360the first time after flashing your device,
361you'll need to remount the filesystems to be writable:
362
363    $ adb root
364    $ adb remount
365    $ adb reboot
366    $ adb wait-for-device
367    $ adb root
368    $ adb remount
369
370Then you can sync your locally built files across:
371
372    $ adb sync
373
374And then you can run the 32-bit tests (dynamic or static):
375
376    $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests
377    $ adb shell \
378        /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static
379
380Or the 64-bit tests (dynamic or static):
381
382    $ adb shell /data/nativetest64/bionic-unit-tests/bionic-unit-tests
383    $ adb shell \
384        /data/nativetest64/bionic-unit-tests-static/bionic-unit-tests-static
385
386Note that we use our own custom gtest runner that offers a superset of the
387options documented at
388<https://github.com/google/googletest/blob/main/docs/advanced.md#running-test-programs-advanced-options>,
389in particular for test isolation and parallelism (both on by default).
390
391### Device tests via CTS
392
393Most of the unit tests are executed by CTS. By default, CTS runs as
394a non-root user, so the unit tests must also pass when not run as root.
395Some tests cannot do any useful work unless run as root. In this case,
396the test should check `getuid() == 0` and do nothing otherwise (typically
397we log in this case to prevent accidents!). Obviously, if the test can be
398rewritten to not require root, that's an even better solution.
399
400Currently, the list of bionic CTS tests is generated at build time by
401running a host version of the test executable and dumping the list of
402all tests. In order for this to continue to work, all architectures must
403have the same number of tests, and the host version of the executable
404must also have the same number of tests.
405
406Running the gtests directly is orders of magnitude faster than using CTS,
407but in cases where you really have to run CTS:
408
409    $ make cts # In $ANDROID_ROOT.
410    $ adb unroot # Because real CTS doesn't run as root.
411    # This will sync any *test* changes, but not *code* changes:
412    $ cts-tradefed \
413        run singleCommand cts --skip-preconditions -m CtsBionicTestCases
414
415### Host tests
416
417The host tests require that you have `lunch`ed either an x86 or x86_64 target.
418
419(Obviously, in theory you could build for arm64 and run on an arm64 host,
420but we currently only support x86-64 host builds.)
421
422For example:
423
424    $ lunch aosp_cf_x86_64_phone-trunk_staging-userdebug
425
426Then build as normal:
427
428    $ cd bionic
429    $ mm
430
431Note that due to ABI limitations (specifically, the size of pthread_mutex_t),
43232-bit bionic requires PIDs less than 65536.
433To enforce this, set /proc/sys/kernel/pid_max to 65536.
434(The tests will remind you if you forget.)
435
436The easiest way to run is to use our provided script.
437
438To run the 32-bit tests on the host:
439
440    $ ./tests/run-on-host.sh 32
441
442To run the 64-bit tests on the host:
443
444    $ ./tests/run-on-host.sh 64
445
446You can supply gtest flags as extra arguments to this script.
447
448This script starts by running build/run-on-host.sh which -- despite the name --
449is actually a script to set up your host to look more like an Android device.
450In particular, it creates a /system directory with appropriate symlinks to your
451"out" directory.
452
453An alternative is to run the static binaries directly from your "out" directory.
454
455To run the static 32-bit tests:
456
457    $ ../out/target/product/vsoc_x86_64/data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static
458
459To run the static 64-bit tests:
460
461    $ ../out/target/product/vsoc_x86_64/data/nativetest64/bionic-unit-tests-static/bionic-unit-tests-static
462
463
464### Against glibc
465
466As a way to check that our tests do in fact test the correct behavior (and not
467just the behavior we think is correct), it is possible to run the tests against
468the host's glibc.
469
470    $ ./tests/run-on-host.sh glibc
471
472### Against musl
473
474Another way to verify test behavior is to run against musl on the host. glibc
475musl don't always match, so this can be a good way to find the more complicated
476corners of the spec. If they *do* match, bionic probably should too!
477
478    $ OUT_DIR=$(ANDROID_BUILD_TOP)/musl-out ./tests/run-on-host.sh musl
479
480Note: the alternate OUT_DIR is used to avoid causing excessive rebuilding when
481switching between glibc and musl. The first musl test run will be expensive
482because it will not reuse any already built artifacts, but subsequent runs will
483be cheaper than if you hadn't used it.
484
485## Gathering test coverage
486
487To get test coverage for bionic, use `//bionic/build/coverage.sh`. Before
488running, follow the instructions at the top of the file to rebuild bionic with
489coverage instrumentation.
490
491## Attaching GDB to the tests
492
493Bionic's test runner will run each test in its own process by default to prevent
494tests failures from impacting other tests. This also has the added benefit of
495running them in parallel, so they are much faster.
496
497However, this also makes it difficult to run the tests under GDB. To prevent
498each test from being forked, run the tests with the flag `--no-isolate`.
499
500
501## 32-bit ABI bugs
502
503See [32-bit ABI bugs](docs/32-bit-abi.md).
504