This articleneeds additional citations forverification. Please helpimprove this article byadding citations to reliable sources. Unsourced material may be challenged and removed. Find sources: "Bionic" software – news ·newspapers ·books ·scholar ·JSTOR(September 2025) (Learn how and when to remove this message) |
Bionic is an implementation of theC standard library, developed byGoogle for itsAndroidoperating system. It differs from theGNU C Library (glibc) in being designed for devices with less memory and processor power than a typicalLinux system. It is a combination of new code and code fromFreeBSD,NetBSD, andOpenBSD released under aBSD license, rather than glibc, which uses theGNU Lesser General Public License. This difference was important in the early days of Android, whenstatic linking was common, and since Bionic has its ownapplication binary interface, it cannot be replaced by a different libc without breaking all existing apps.
Bionic is a C library for use with theLinux kernel, and provideslibc,libdl, andlibm (libpthread functionality is part oflibc, not a separate library as on some other systems). This differs from theBSD C libraries that Bionic shares code with, because they require a BSDkernel.
The original publicly stated goals for Bionic were the following:[1][2]
Bionic only supports Linux kernels, but currently supports the arm, arm64, riscv64,x86, andx86-64 architectures. The platform itself required armv7 withNeon sinceMarshmallow,[5] though theAndroid Native Development Kit (NDK) continued to support armv5 (which it called armeabi) up until NDK r16. The NDK still supports armv7, though NDK r24 dropped support for non-Neon. Historically there was partialSH-4 support in the platform, but no devices ever shipped and support has since been removed. The NDK never supported SH-4, andMIPS and MIPS64 support were removed from the NDK in r17.
Some parts of the libc source, such asstdio, are from the BSDs (mainlyOpenBSD), whereas others, such as thepthread implementation, were written from scratch.
Thedynamic memory allocator implementation has changed over time. BeforeLollipop there was a single native memory allocator, Doug Lea'sdlmalloc. For Lollipop and Marshmallow there were two implementations: dlmalloc andjemalloc. jemalloc gives much higher performance than dlmalloc, but at the cost of extra memory required for bookkeeping. Most devices used jemalloc but low-memory devices still used dlmalloc. ForNougat throughAndroid 10, all devices use jemalloc. Low-memory devices use a "svelte" configuration of jemalloc that disables the tcache to nearly match the lower memory overhead of dlmalloc while keeping most of the speed of jemalloc. InAndroid 11, the memory allocator for most devices was switched toScudo, which sacrifices some of jemalloc's high performance for additional security hardening features.[6] Low-memory devices, however, are still permitted to use jemalloc.[7]
Some64-bit devices, like theNexus 9, are effectively low-memory devices because of the extra space requirements of 64-bit pointers and hosting of two zygotes. (Zygote is an Android system service that is the parent of all Android application processes.[8])
Thelibm source is largelyFreeBSD's, but with optimized assembler contributed by the variousSoC vendors.
The dynamic linker (and libdl) were written from scratch.
Bionic doesn't include libthread_db (used bygdbserver), but the NDK did. The Android platform included a statically linked gdbserver, so that developers can use the latestgdb even on old devices. Since Android dropped gdb support and switched to lldb, this is no longer relevant.
There is no separate libpthread, libresolv, or librt on Android – the functionality is all in libc. For libpthread, there is no attempt to optimize for the single-threaded case because apps are in a multi-threaded environment even before the first instruction of third-party code is ever run.
The Android platform uses libc++ for the C++ standard library (releases up to and including Lollipop used stlport). The NDK historically offered stlport and GNU libstdc++, but those were removed as of NDK r18.[9] Note that if any native code in an Android app uses C++, all the C++ must use thesameSTL. The STL is not provided by the Android OS, and must be bundled with each app.
Although Bionic aims to implement all ofC11 andPOSIX, there are still (as of Android 15) about 11 POSIX functions missing[10] from libc. There are also POSIX functions such as the endpwent/getpwent/setpwent family that are inapplicable to Android because it lacks apasswd database. As ofOreo, libm is complete.
Some functions deliberately do not conform to the POSIX or C standards for security reasons, such asprintf which does not support the%n format string.[11]
Many of the most-used GNU extensions are implemented in Bionic, as are various BSD extensions.
Platform code uses Bionic directly, but third-party developers use the Android Native Development Kit (NDK). Many third-party developers still target older OS releases, which contributes to a widespread belief that Bionic lacks many features.Gingerbread exported 803 functions from libc but Oreo exports 1278 (a 1.6x increase).[10]
Historically the NDK and the platform diverged, but NDK r11 and later have replaced NDK forks with their current platform equivalents. This work initially focused on theGCC andClang compilers.
Prior to NDK r14, when "unified" headers were first offered on an opt-in basis, the NDK had forked copies of the platform headers for different API levels. This meant that header-only fixes (fixes to constant or structure definitions, for example) weren't available to most NDK users because they'd be targeting an older API level, but platform fixes were only going in to the current platform headers. In the Oreo development period the platform headers were annotated with API level information so that the same set of headers can be used for all API levels, with only those functions available at the developer's targeted API level being visible. These are the so-called "unified" headers, and have been the default since NDK r15.
Prior to NDK r16, the NDK linked a library called libandroid_support.a to code using libc++ to provide functions required by libc++ that weren't in old OS releases. This wasn't the same code used by the platform and introduced numerous bugs (such as breaking positional arguments to the printf family in any code that used libc++). From NDK r16 to r25, libandroid_support.a still existed but was built directly from the then-current platform source at the time each NDK was built. From NDK r26, libandroid_support.a is gone, because all OS versions still supported by the NDK contain everything needed by libc++.
As ofAndroid Jelly Bean MR1 (4.2), Bionic supports similar functionality to glibc's_FORTIFY_SOURCE,[12] which is a feature whereunsafe string and memory functions (such asstrcpy(),strcat(), andmemcpy()) include checks for buffer overruns. These checks are performed at compile time if the buffer sizes can be determined at compile time, or run-time otherwise. Because fortify relies on runtime support from libc, its portability to older Android releases is limited.[13] The platform itself is built with_FORTIFY_SOURCE enabled.
Historically, one of the shortcomings of fortify has been that it is closely tied with GCC, which makes it very difficult to support well in other compilers, like Clang. This meant that when Android swapped to Clang as its default compiler,[14] Bionic's fortify implementation became substantially less useful. In Android Oreo (8.0), Bionic's fortify was overhauled[15] with Clang in mind, resulting in fortify on Clang providing an experience on par with fortify on GCC. Since this overhaul, some checks were added above and beyond glibc's to catch code that — while not necessarily causing undefined behavior — is obviously incorrect. Because this new implementation requires no more libc support than the prior one, the Clang-specific enhancements are available to applications targeting versions of Android before Oreo.
For the creation of Bionic, Google used GPLv2-licensed Linux kernelheader files. To get rid of the GPL, Google claimed that it cleaned the header files from any copyright-able work, reducing them to non-copyrightable "facts".[16][17] Linux creatorLinus Torvalds considered Google's behaviour to be acceptable,[17] but Google's interpretation of the GPL has been challenged, for instance by Raymond Nimmer, a law professor at theUniversity of Houston Law Center.[18]
The name "Bionic" comes from the fact that it is part-BSD and part-Linux: its source code consists in a mix of BSD C library pieces with custom Linux-specific bits used to deal with threads, processes, signals and a few others things.
License: we want to keep GPL out of user-space