1Working on bionic 2================= 3 4What are the big pieces of bionic? 5---------------------------------- 6 7#### libc/ --- libc.so, libc.a 8 9The C library. Stuff like `fopen(3)` and `kill(2)`. 10 11#### libm/ --- libm.so, libm.a 12 13The math library. Traditionally Unix systems kept stuff like `sin(3)` and 14`cos(3)` in a separate library to save space in the days before shared 15libraries. 16 17#### libdl/ --- libdl.so 18 19The dynamic linker interface library. This is actually just a bunch of stubs 20that the dynamic linker replaces with pointers to its own implementation at 21runtime. This is where stuff like `dlopen(3)` lives. 22 23#### libstdc++/ --- libstdc++.so 24 25The C++ ABI support functions. The C++ compiler doesn't know how to implement 26thread-safe static initialization and the like, so it just calls functions that 27are supplied by the system. Stuff like `__cxa_guard_acquire` and 28`__cxa_pure_virtual` live here. 29 30#### linker/ --- /system/bin/linker and /system/bin/linker64 31 32The dynamic linker. When you run a dynamically-linked executable, its ELF file 33has a `DT_INTERP` entry that says "use the following program to start me". On 34Android, that's either `linker` or `linker64` (depending on whether it's a 3532-bit or 64-bit executable). It's responsible for loading the ELF executable 36into memory and resolving references to symbols (so that when your code tries to 37jump to `fopen(3)`, say, it lands in the right place). 38 39#### tests/ --- unit tests 40 41The `tests/` directory contains unit tests. Roughly arranged as one file per 42publicly-exported header file. 43 44#### benchmarks/ --- benchmarks 45 46The `benchmarks/` directory contains benchmarks. 47 48 49What's in libc/? 50---------------- 51 52<pre> 53libc/ 54 arch-arm/ 55 arch-arm64/ 56 arch-common/ 57 arch-mips/ 58 arch-mips64/ 59 arch-x86/ 60 arch-x86_64/ 61 # Each architecture has its own subdirectory for stuff that isn't shared 62 # because it's architecture-specific. There will be a .mk file in here that 63 # drags in all the architecture-specific files. 64 bionic/ 65 # Every architecture needs a handful of machine-specific assembler files. 66 # They live here. 67 include/ 68 machine/ 69 # The majority of header files are actually in libc/include/, but many 70 # of them pull in a <machine/something.h> for things like limits, 71 # endianness, and how floating point numbers are represented. Those 72 # headers live here. 73 string/ 74 # Most architectures have a handful of optional assembler files 75 # implementing optimized versions of various routines. The <string.h> 76 # functions are particular favorites. 77 syscalls/ 78 # The syscalls directories contain script-generated assembler files. 79 # See 'Adding system calls' later. 80 81 include/ 82 # The public header files on everyone's include path. These are a mixture of 83 # files written by us and files taken from BSD. 84 85 kernel/ 86 # The kernel uapi header files. These are scrubbed copies of the originals 87 # in external/kernel-headers/. These files must not be edited directly. The 88 # generate_uapi_headers.sh script should be used to go from a kernel tree to 89 # external/kernel-headers/ --- this takes care of the architecture-specific 90 # details. The update_all.py script should be used to regenerate bionic's 91 # scrubbed headers from external/kernel-headers/. 92 93 private/ 94 # These are private header files meant for use within bionic itself. 95 96 dns/ 97 # Contains the DNS resolver (originates from NetBSD code). 98 99 upstream-dlmalloc/ 100 upstream-freebsd/ 101 upstream-netbsd/ 102 upstream-openbsd/ 103 # These directories contain unmolested upstream source. Any time we can 104 # just use a BSD implementation of something unmodified, we should. 105 # The structure under these directories mimics the upstream tree, 106 # but there's also... 107 android/ 108 include/ 109 # This is where we keep the hacks necessary to build BSD source 110 # in our world. The *-compat.h files are automatically included 111 # using -include, but we also provide equivalents for missing 112 # header/source files needed by the BSD implementation. 113 114 bionic/ 115 # This is the biggest mess. The C++ files are files we own, typically 116 # because the Linux kernel interface is sufficiently different that we 117 # can't use any of the BSD implementations. The C files are usually 118 # legacy mess that needs to be sorted out, either by replacing it with 119 # current upstream source in one of the upstream directories or by 120 # switching the file to C++ and cleaning it up. 121 122 stdio/ 123 # These are legacy files of dubious provenance. We're working to clean 124 # this mess up, and this directory should disappear. 125 126 tools/ 127 # Various tools used to maintain bionic. 128 129 tzcode/ 130 # A modified superset of the IANA tzcode. Most of the modifications relate 131 # to Android's use of a single file (with corresponding index) to contain 132 # time zone data. 133 zoneinfo/ 134 # Android-format time zone data. 135 # See 'Updating tzdata' later. 136</pre> 137 138 139Adding system calls 140------------------- 141 142Adding a system call usually involves: 143 144 1. Add entries to SYSCALLS.TXT. 145 See SYSCALLS.TXT itself for documentation on the format. 146 2. Run the gensyscalls.py script. 147 3. Add constants (and perhaps types) to the appropriate header file. 148 Note that you should check to see whether the constants are already in 149 kernel uapi header files, in which case you just need to make sure that 150 the appropriate POSIX header file in libc/include/ includes the 151 relevant file or files. 152 4. Add function declarations to the appropriate header file. 153 5. Add at least basic tests. Even a test that deliberately supplies 154 an invalid argument helps check that we're generating the right symbol 155 and have the right declaration in the header file. (And strace(1) can 156 confirm that the correct system call is being made.) 157 158 159Updating kernel header files 160---------------------------- 161 162As mentioned above, this is currently a two-step process: 163 164 1. Use generate_uapi_headers.sh to go from a Linux source tree to appropriate 165 contents for external/kernel-headers/. 166 2. Run update_all.py to scrub those headers and import them into bionic. 167 168 169Updating tzdata 170--------------- 171 172This is fully automated: 173 174 1. Run update-tzdata.py. 175 176 177Verifying changes 178----------------- 179 180If you make a change that is likely to have a wide effect on the tree (such as a 181libc header change), you should run `make checkbuild`. A regular `make` will 182_not_ build the entire tree; just the minimum number of projects that are 183required for the device. Tests, additional developer tools, and various other 184modules will not be built. Note that `make checkbuild` will not be complete 185either, as `make tests` covers a few additional modules, but generally speaking 186`make checkbuild` is enough. 187 188 189Running the tests 190----------------- 191 192The tests are all built from the tests/ directory. 193 194### Device tests 195 196 $ mma 197 $ adb sync 198 $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests32 199 $ adb shell \ 200 /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static32 201 # Only for 64-bit targets 202 $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests64 203 $ adb shell \ 204 /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static64 205 206### Host tests 207 208The host tests require that you have `lunch`ed either an x86 or x86_64 target. 209 210 $ mma 211 $ mm bionic-unit-tests-run-on-host32 212 $ mm bionic-unit-tests-run-on-host64 # For 64-bit *targets* only. 213 214### Against glibc 215 216As a way to check that our tests do in fact test the correct behavior (and not 217just the behavior we think is correct), it is possible to run the tests against 218the host's glibc. The executables are already in your path. 219 220 $ mma 221 $ bionic-unit-tests-glibc32 222 $ bionic-unit-tests-glibc64 223 224 225Gathering test coverage 226----------------------- 227 228For either host or target coverage, you must first: 229 230 * `$ export NATIVE_COVERAGE=true` 231 * Note that the build system is ignorant to this flag being toggled, i.e. if 232 you change this flag, you will have to manually rebuild bionic. 233 * Set `bionic_coverage=true` in `libc/Android.mk` and `libm/Android.mk`. 234 235### Coverage from device tests 236 237 $ mma 238 $ adb sync 239 $ adb shell \ 240 GCOV_PREFIX=/data/local/tmp/gcov \ 241 GCOV_PREFIX_STRIP=`echo $ANDROID_BUILD_TOP | grep -o / | wc -l` \ 242 /data/nativetest/bionic-unit-tests/bionic-unit-tests32 243 $ acov 244 245`acov` will pull all coverage information from the device, push it to the right 246directories, run `lcov`, and open the coverage report in your browser. 247 248### Coverage from host tests 249 250First, build and run the host tests as usual (see above). 251 252 $ croot 253 $ lcov -c -d $ANDROID_PRODUCT_OUT -o coverage.info 254 $ genhtml -o covreport coverage.info # or lcov --list coverage.info 255 256The coverage report is now available at `covreport/index.html`. 257 258 259LP32 ABI bugs 260------------- 261 262This probably belongs in the NDK documentation rather than here, but these 263are the known ABI bugs in LP32: 264 265 * `time_t` is 32-bit. <http://b/5819737> 266 267 * `off_t` is 32-bit. There is `off64_t`, but no `_FILE_OFFSET_BITS` support. 268 Many of the `off64_t` functions are missing in older releases, and 269 stdio uses 32-bit offsets, so there's no way to fully implement 270 `_FILE_OFFSET_BITS`. 271 272 * `sigset_t` is too small on ARM and x86 (but correct on MIPS), so support 273 for real-time signals is broken. <http://b/5828899> 274