diff options
author | Dan Albert <danalbert@google.com> | 2014-10-09 22:57:49 -0700 |
---|---|---|
committer | Dan Albert <danalbert@google.com> | 2014-10-10 11:45:19 -0700 |
commit | efee1ce46a0808a998c8ef6ba232fbabcb4531b1 (patch) | |
tree | f8396cb9a44b5ec94aaa2c9ec036fe572f190f71 /README.md | |
parent | e9c216fca56e84b0d0a96f7d5e3c99d3276ef071 (diff) | |
download | bionic-efee1ce46a0808a998c8ef6ba232fbabcb4531b1.zip bionic-efee1ce46a0808a998c8ef6ba232fbabcb4531b1.tar.gz bionic-efee1ce46a0808a998c8ef6ba232fbabcb4531b1.tar.bz2 |
Improve documentation for testing and coverage.
Also rename HACKING.txt to README.md so it will display on the GitHub
mirror.
Change-Id: I70157a4ad262700212bf9afd87253d195c7013a9
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..143c762 --- /dev/null +++ b/README.md @@ -0,0 +1,233 @@ +Working on bionic +================= + +What are the big pieces of bionic? +---------------------------------- + +libc/ --- libc.so, libc.a + The C library. Stuff like fopen(3) and kill(2). +libm/ --- libm.so, libm.a + The math library. Traditionally Unix systems kept stuff like sin(3) and + cos(3) in a separate library to save space in the days before shared + libraries. +libdl/ --- libdl.so + The dynamic linker interface library. This is actually just a bunch of + stubs that the dynamic linker replaces with pointers to its own + implementation at runtime. This is where stuff like dlopen(3) lives. +libstdc++/ --- libstdc++.so + The C++ ABI support functions. The C++ compiler doesn't know how to + implement thread-safe static initialization and the like, so it just calls + functions that are supplied by the system. Stuff like __cxa_guard_acquire + and __cxa_pure_virtual live here. + +linker/ --- /system/bin/linker and /system/bin/linker64 + The dynamic linker. When you run a dynamically-linked executable, its ELF + file has a DT_INTERP entry that says "use the following program to start me". + On Android, that's either linker or linker64 (depending on whether it's a + 32-bit or 64-bit executable). It's responsible for loading the ELF executable + into memory and resolving references to symbols (so that when your code tries + to jump to fopen(3), say, it lands in the right place). + +tests/ --- unit tests + The tests/ directory contains unit tests. Roughly arranged as one file per + publicly-exported header file. +benchmarks/ --- benchmarks + The benchmarks/ directory contains benchmarks. + + +What's in libc/? +---------------- + +libc/ + arch-arm/ + arch-arm64/ + arch-common/ + arch-mips/ + arch-mips64/ + arch-x86/ + arch-x86_64/ + # Each architecture has its own subdirectory for stuff that isn't shared + # because it's architecture-specific. There will be a .mk file in here that + # drags in all the architecture-specific files. + bionic/ + # Every architecture needs a handful of machine-specific assembler files. + # They live here. + include/ + machine/ + # The majority of header files are actually in libc/include/, but many + # of them pull in a <machine/something.h> for things like limits, + # endianness, and how floating point numbers are represented. Those + # headers live here. + string/ + # Most architectures have a handful of optional assembler files + # implementing optimized versions of various routines. The <string.h> + # functions are particular favorites. + syscalls/ + # The syscalls directories contain script-generated assembler files. + # See 'Adding system calls' later. + + include/ + # The public header files on everyone's include path. These are a mixture of + # files written by us and files taken from BSD. + + kernel/ + # The kernel uapi header files. These are scrubbed copies of the originals + # in external/kernel-headers/. These files must not be edited directly. The + # generate_uapi_headers.sh script should be used to go from a kernel tree to + # external/kernel-headers/ --- this takes care of the architecture-specific + # details. The update_all.py script should be used to regenerate bionic's + # scrubbed headers from external/kernel-headers/. + + private/ + # These are private header files meant for use within bionic itself. + + dns/ + # Contains the DNS resolver (originates from NetBSD code). + + upstream-dlmalloc/ + upstream-freebsd/ + upstream-netbsd/ + upstream-openbsd/ + # These directories contain unmolested upstream source. Any time we can + # just use a BSD implementation of something unmodified, we should. + # The structure under these directories mimics the upstream tree, + # but there's also... + android/ + include/ + # This is where we keep the hacks necessary to build BSD source + # in our world. The *-compat.h files are automatically included + # using -include, but we also provide equivalents for missing + # header/source files needed by the BSD implementation. + + bionic/ + # This is the biggest mess. The C++ files are files we own, typically + # because the Linux kernel interface is sufficiently different that we + # can't use any of the BSD implementations. The C files are usually + # legacy mess that needs to be sorted out, either by replacing it with + # current upstream source in one of the upstream directories or by + # switching the file to C++ and cleaning it up. + + stdio/ + # These are legacy files of dubious provenance. We're working to clean + # this mess up, and this directory should disappear. + + tools/ + # Various tools used to maintain bionic. + + tzcode/ + # A modified superset of the IANA tzcode. Most of the modifications relate + # to Android's use of a single file (with corresponding index) to contain + # time zone data. + zoneinfo/ + # Android-format time zone data. + # See 'Updating tzdata' later. + + +Adding system calls +------------------- + +Adding a system call usually involves: + + 1. Add entries to SYSCALLS.TXT. + See SYSCALLS.TXT itself for documentation on the format. + 2. Run the gensyscalls.py script. + 3. Add constants (and perhaps types) to the appropriate header file. + Note that you should check to see whether the constants are already in + kernel uapi header files, in which case you just need to make sure that + the appropriate POSIX header file in libc/include/ includes the + relevant file or files. + 4. Add function declarations to the appropriate header file. + 5. Add at least basic tests. Even a test that deliberately supplies + an invalid argument helps check that we're generating the right symbol + and have the right declaration in the header file. (And strace(1) can + confirm that the correct system call is being made.) + + +Updating kernel header files +---------------------------- + +As mentioned above, this is currently a two-step process: + + 1. Use generate_uapi_headers.sh to go from a Linux source tree to appropriate + contents for external/kernel-headers/. + 2. Run update_all.py to scrub those headers and import them into bionic. + + +Updating tzdata +--------------- + +This is fully automated: + + 1. Run update-tzdata.py. + + +Running the tests +----------------- + +The tests are all built from the tests/ directory. + +### Device tests + + $ mma + $ adb sync + $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests32 + $ adb shell \ + /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static32 + # Only for 64-bit targets + $ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests64 + $ adb shell \ + /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static64 + +### Host tests + +The host tests require that you have `lunch`ed either an x86 or x86_64 target. + + $ mma + # 64-bit tests for 64-bit targets, 32-bit otherwise. + $ mm bionic-unit-tests-run-on-host + # Only exists for 64-bit targets. + $ mm bionic-unit-tests-run-on-host32 + +### Against glibc + +As a way to check that our tests do in fact test the correct behavior (and not +just the behavior we think is correct), it is possible to run the tests against +the host's glibc. + + $ mma + $ bionic-unit-tests-glibc32 # already in your path + $ bionic-unit-tests-glibc64 + + +Gathering test coverage +----------------------- + +For either host or target coverage, you must first: + + * `$ export NATIVE_COVERAGE=true` + * Note that the build system is ignorant to this flag being toggled, i.e. if + you change this flag, you will have to manually rebuild bionic. + * Set `bionic_coverage=true` in `libc/Android.mk` and `libm/Android.mk`. + +### Coverage from device tests + + $ mma + $ adb sync + $ adb shell \ + GCOV_PREFIX=/data/local/tmp/gcov \ + GCOV_PREFIX_STRIP=`echo $ANDROID_BUILD_TOP | grep -o / | wc -l` \ + /data/nativetest/bionic-unit-tests/bionic-unit-tests32 + $ acov + +`acov` will pull all coverage information from the device, push it to the right +directories, run `lcov`, and open the coverage report in your browser. + +### Coverage from host tests + +First, build and run the host tests as usual (see above). + + $ croot + $ lcov -c -d $ANDROID_PRODUCT_OUT -o coverage.info + $ genhtml -o covreport coverage.info # or lcov --list coverage.info + +The coverage report is now available at `covreport/index.html`. |