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