• Home
Name Date Size #Lines LOC

..--

apex/06-Sep-2024-418368

benchmarks/06-Sep-2024-577,887575,202

build/06-Sep-2024-333261

docs/06-Sep-2024-3,7012,949

libc/06-Sep-2024-324,755241,874

libdl/06-Sep-2024-800584

libfdtrack/06-Sep-2024-544395

libm/06-Sep-2024-31,84118,965

libstdc++/06-Sep-2024-6550

linker/06-Sep-2024-18,26911,858

tests/06-Sep-2024-301,547279,754

tools/06-Sep-2024-6,3145,030

.clang-formatD06-Sep-2024239

.gitignoreD06-Sep-202411 32

CPPLINT.cfgD06-Sep-202475 32

CleanSpec.mkD06-Sep-20243 KiB688

METADATAD06-Sep-202439 43

OWNERSD06-Sep-2024119 86

PREUPLOAD.cfgD06-Sep-2024278 107

README.mdD06-Sep-202419.1 KiB432336

TEST_MAPPINGD06-Sep-20241.5 KiB9998

android-changes-for-ndk-developers.mdD06-Sep-202422.9 KiB512387

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)](http://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
2711. Key error for a new codename in libc/libc.map.txt
272
273e.g. what you add in libc/libc.map.txt is:
274
275```
276LIBC_V { # introduced=Vanilla
277  global:
278    xxx; // the new system call you add
279} LIBC_U;
280```
281
282The error output is:
283
284```
285Traceback (most recent call last):
286  File "/path/tp/out/soong/.temp/Soong.python_qucjwd7g/symbolfile/__init__.py", line 171,
287  in decode_api_level_tag
288    decoded = str(decode_api_level(value, api_map))
289  File "/path/to/out/soong/.temp/Soong.python_qucjwd7g/symbolfile/__init__.py", line 157,
290  in decode_api_level
291    return api_map[api]
292KeyError: 'Vanilla'
293```
294
295Solution: Ask in the team and wait for the update.
296
2972. Use of undeclared identifier of the new system call in the test
298
299Possible Solution: Check everything ready in the files mentioned above first.
300Maybe glibc matters. Follow the example and try #if defined(__GLIBC__).
301
302## Updating kernel header files
303
304As mentioned above, this is currently a two-step process:
305
306  1. Use generate_uapi_headers.sh to go from a Linux source tree to appropriate
307     contents for external/kernel-headers/.
308  2. Run update_all.py to scrub those headers and import them into bionic.
309
310Note that if you're actually just trying to expose device-specific headers to
311build your device drivers, you shouldn't modify bionic. Instead use
312`TARGET_DEVICE_KERNEL_HEADERS` and friends described in [config.mk](https://android.googlesource.com/platform/build/+/main/core/config.mk#186).
313
314
315## Updating tzdata
316
317This is handled by the libcore team, because they own icu, and that needs to be
318updated in sync with bionic). See
319[system/timezone/README.android](https://android.googlesource.com/platform/system/timezone/+/main/README.android).
320
321
322## Verifying changes
323
324If you make a change that is likely to have a wide effect on the tree (such as a
325libc header change), you should run `make checkbuild`. A regular `make` will
326_not_ build the entire tree; just the minimum number of projects that are
327required for the device. Tests, additional developer tools, and various other
328modules will not be built. Note that `make checkbuild` will not be complete
329either, as `make tests` covers a few additional modules, but generally speaking
330`make checkbuild` is enough.
331
332
333## Running the tests
334
335The tests are all built from the tests/ directory. There is a separate
336directory `benchmarks/` containing benchmarks, and that has its own
337documentation on [running the benchmarks](benchmarks/README.md).
338
339### Device tests
340
341    $ mma # In $ANDROID_ROOT/bionic.
342    $ adb root && adb remount && adb sync
343    $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests
344    $ adb shell \
345        /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static
346    # Only for 64-bit targets
347    $ adb shell /data/nativetest64/bionic-unit-tests/bionic-unit-tests
348    $ adb shell \
349        /data/nativetest64/bionic-unit-tests-static/bionic-unit-tests-static
350
351Note that we use our own custom gtest runner that offers a superset of the
352options documented at
353<https://github.com/google/googletest/blob/main/docs/advanced.md#running-test-programs-advanced-options>,
354in particular for test isolation and parallelism (both on by default).
355
356### Device tests via CTS
357
358Most of the unit tests are executed by CTS. By default, CTS runs as
359a non-root user, so the unit tests must also pass when not run as root.
360Some tests cannot do any useful work unless run as root. In this case,
361the test should check `getuid() == 0` and do nothing otherwise (typically
362we log in this case to prevent accidents!). Obviously, if the test can be
363rewritten to not require root, that's an even better solution.
364
365Currently, the list of bionic CTS tests is generated at build time by
366running a host version of the test executable and dumping the list of
367all tests. In order for this to continue to work, all architectures must
368have the same number of tests, and the host version of the executable
369must also have the same number of tests.
370
371Running the gtests directly is orders of magnitude faster than using CTS,
372but in cases where you really have to run CTS:
373
374    $ make cts # In $ANDROID_ROOT.
375    $ adb unroot # Because real CTS doesn't run as root.
376    # This will sync any *test* changes, but not *code* changes:
377    $ cts-tradefed \
378        run singleCommand cts --skip-preconditions -m CtsBionicTestCases
379
380### Host tests
381
382The host tests require that you have `lunch`ed either an x86 or x86_64 target.
383Note that due to ABI limitations (specifically, the size of pthread_mutex_t),
38432-bit bionic requires PIDs less than 65536. To enforce this, set /proc/sys/kernel/pid_max
385to 65536.
386
387    $ ./tests/run-on-host.sh 32
388    $ ./tests/run-on-host.sh 64   # For x86_64-bit *targets* only.
389
390You can supply gtest flags as extra arguments to this script.
391
392### Against glibc
393
394As a way to check that our tests do in fact test the correct behavior (and not
395just the behavior we think is correct), it is possible to run the tests against
396the host's glibc.
397
398    $ ./tests/run-on-host.sh glibc
399
400### Against musl
401
402Another way to verify test behavior is to run against musl on the host. glibc
403musl don't always match, so this can be a good way to find the more complicated
404corners of the spec. If they *do* match, bionic probably should too!
405
406    $ OUT_DIR=$(ANDROID_BUILD_TOP)/musl-out ./tests/run-on-host.sh musl
407
408Note: the alternate OUT_DIR is used to avoid causing excessive rebuilding when
409switching between glibc and musl. The first musl test run will be expensive
410because it will not reuse any already built artifacts, but subsequent runs will
411be cheaper than if you hadn't used it.
412
413## Gathering test coverage
414
415To get test coverage for bionic, use `//bionic/build/coverage.sh`. Before
416running, follow the instructions at the top of the file to rebuild bionic with
417coverage instrumentation.
418
419## Attaching GDB to the tests
420
421Bionic's test runner will run each test in its own process by default to prevent
422tests failures from impacting other tests. This also has the added benefit of
423running them in parallel, so they are much faster.
424
425However, this also makes it difficult to run the tests under GDB. To prevent
426each test from being forked, run the tests with the flag `--no-isolate`.
427
428
429## 32-bit ABI bugs
430
431See [32-bit ABI bugs](docs/32-bit-abi.md).
432