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