Bionic (software)

Last updated

Bionic is an implementation of the standard C library, developed by Google for its Android operating system. It differs from the GNU C Library (glibc) in being designed for devices with less memory and processor power than a typical Linux system. It is a combination of new code and code from FreeBSD, NetBSD, and OpenBSD released under a BSD license, rather than glibc, which uses the GNU Lesser General Public License. This difference was important in the early days of Android, when static linking was common, and since bionic has its own ABI, it can't be replaced by a different libc without breaking all existing apps.

Contents

Bionic is a C library for use with the Linux kernel, and provides libc, libdl, and libm (libpthread functionality is part of libc, not a separate library as on some other systems). This differs from the BSD C libraries that bionic shares code with, because they require a BSD kernel.

Original goals

The original publicly stated goals for Bionic were the following: [1] [2]

Supported architectures

Bionic only supports Linux kernels, but currently supports the arm, arm64, riscv64, x86, and x86-64 architectures. The platform itself required armv7 with Neon since Marshmallow, [5] though the Android 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 partial SH-4 support in the platform, but no devices ever shipped and support has since been removed. The NDK never supported SH-4, and MIPS and MIPS64 support were removed from the NDK in r17.

Components

Some parts of the libc source, such as stdio, are from the BSDs (mainly OpenBSD), whereas others, such as the pthread implementation, were written from scratch.

The dynamic memory allocator implementation has changed over time. Before Lollipop there was a single native memory allocator, Doug Lea's dlmalloc. For Lollipop and Marshmallow there were two implementations: dlmalloc and jemalloc. 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. For Nougat through Android 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. In Android 11, the memory allocator for most devices was switched to Scudo, 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]

Some 64-bit devices, like the Nexus 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] )

The libm source is largely FreeBSD's, but with optimized assembler contributed by the various SoC vendors.

The dynamic linker (and libdl) were written from scratch.

Bionic doesn't include libthread_db (used by gdbserver), but the NDK did. The Android platform included a statically linked gdbserver, so that developers can use the latest gdb 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's 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 the same STL. The STL is not provided by the Android OS, and must be bundled with each app.

Differences from POSIX

Although Bionic aims to implement all of C11 and POSIX, there are still (as of Oreo) about 70 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 a passwd database. As of Oreo, libm is complete.

Some functions deliberately do not conform to the POSIX or C standards for security reasons, such as printf 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.

Relationship to the NDK

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 the GCC and Clang 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++.

Fortify source

As of Android Jelly Bean MR1 (4.2), Bionic supports similar functionality to glibc's _FORTIFY_SOURCE, [12] which is a feature where unsafe string and memory functions (such as strcpy(), strcat(), and memcpy()) 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.

Controversies

For the creation of Bionic, Google used GPLv2-licensed Linux kernel header 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 creator Linus 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 the University of Houston Law Center. [18]

See also

Related Research Articles

<span class="mw-page-title-main">Executable and Linkable Format</span> Standard file format for executables, object code, shared libraries, and core dumps.

In computing, the Executable and Linkable Format, is a common standard file format for executable files, object code, shared libraries, and core dumps. First published in the specification for the application binary interface (ABI) of the Unix operating system version named System V Release 4 (SVR4), and later in the Tool Interface Standard, it was quickly accepted among different vendors of Unix systems. In 1999, it was chosen as the standard binary file format for Unix and Unix-like systems on x86 processors by the 86open project.

<span class="mw-page-title-main">Free software</span> Software licensed to be freely used, modified and distributed

Free software, libre software, or libreware is computer software distributed under terms that allow users to run the software for any purpose as well as to study, change, and distribute it and any adapted versions. Free software is a matter of liberty, not price; all users are legally free to do what they want with their copies of a free software regardless of how much is paid to obtain the program. Computer programs are deemed "free" if they give end-users ultimate control over the software and, subsequently, over their devices.

<span class="mw-page-title-main">GNU Debugger</span> Source-level debugger

The GNU Debugger (GDB) is a portable debugger that runs on many Unix-like systems and works for many programming languages, including Ada, Assembly, C, C++, D, Fortran, Haskell, Go, Objective-C, OpenCL C, Modula-2, Pascal, Rust, and partially others.

<span class="mw-page-title-main">GNU Project</span> Free software project

The GNU Project is a free software, mass collaboration project announced by Richard Stallman on September 27, 1983. Its goal is to give computer users freedom and control in their use of their computers and computing devices by collaboratively developing and publishing software that gives everyone the rights to freely run the software, copy and distribute it, study it, and modify it. GNU software grants these rights in its license.

The GNU C Library, commonly known as glibc, is the GNU Project's implementation of the C standard library. It is a wrapper around the system calls of the Linux kernel for application use. Despite its name, it now also directly supports C++. It was started in the 1980s by the Free Software Foundation (FSF) for the GNU operating system.

The C standard library or libc is the standard library for the C programming language, as specified in the ISO C standard. Starting from the original ANSI C standard, it was developed at the same time as the C library POSIX specification, which is a superset of it. Since ANSI C was adopted by the International Organization for Standardization, the C standard library is also called the ISO C library.

C dynamic memory allocation refers to performing manual memory management for dynamic memory allocation in the C programming language via a group of functions in the C standard library, namely malloc, realloc, calloc, aligned_alloc and free.

<span class="mw-page-title-main">GNU/Linux naming controversy</span> Issues of what to call a system with the GNU toolchain and the Linux kernel

Within the free software and the open-source software communities there is controversy over whether to refer to computer operating systems that use a combination of GNU software and the Linux kernel as "GNU/Linux" or "Linux" systems.

Newlib is a C standard library implementation intended for use on embedded systems. It is a conglomeration of several library parts, all under free software licenses that make them easily usable on embedded products.

<span class="mw-page-title-main">Linux kernel interfaces</span> An overview and comparison of the Linux kernal APIs and ABIs.

The Linux kernel provides multiple interfaces to user-space and kernel-mode code that are used for varying purposes and that have varying properties by design. There are two types of application programming interface (API) in the Linux kernel:

  1. the "kernel–user space" API; and
  2. the "kernel internal" API.
<span class="mw-page-title-main">Linux</span> Family of Unix-like operating systems

Linux is a family of open-source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991, by Linus Torvalds. Linux is typically packaged as a Linux distribution (distro), which includes the kernel and supporting system software and libraries, many of which are provided by the GNU Project. Many Linux distributions use the word "Linux" in their name, but the Free Software Foundation uses and recommends the name "GNU/Linux" to emphasize the use and importance of GNU software in many distributions, causing some controversy.

<span class="mw-page-title-main">FreeBSD</span> Free and open-source Unix-like operating system

FreeBSD is a free and open-source Unix-like operating system descended from the Berkeley Software Distribution (BSD). The first version of FreeBSD was released in 1993 developed from 386BSD and the current version runs on x86, ARM, PowerPC and RISC-V processors. The project is supported and promoted by the FreeBSD Foundation.

GNU variants are operating systems based upon the GNU operating system. According to the GNU project and others, these also include most operating systems using the Linux kernel and a few others using BSD-based kernels.

Clang is a compiler front end for the C, C++, Objective-C, and Objective-C++ programming languages, as well as the OpenMP, OpenCL, RenderScript, CUDA, SYCL, and HIP frameworks. It acts as a drop-in replacement for the GNU Compiler Collection (GCC), supporting most of its compilation flags and unofficial language extensions. It includes a static analyzer, and several code analysis tools.

License compatibility is a legal framework that allows for pieces of software with different software licenses to be distributed together. The need for such a framework arises because the different licenses can contain contradictory requirements, rendering it impossible to legally combine source code from separately-licensed software in order to create and publish a new program. Proprietary licenses are generally program-specific and incompatible; authors must negotiate to combine code. Copyleft licenses are commonly deliberately incompatible with proprietary licenses, in order to prevent copyleft software from being re-licensed under a proprietary license, turning it into proprietary software. Many copyleft licenses explicitly allow relicensing under some other copyleft licenses. Permissive licenses are compatible with everything, including proprietary licenses; there is thus no guarantee that all derived works will remain under a permissive license.

<span class="mw-page-title-main">GNU General Public License</span> Series of free software licenses

The GNU General Public License is a series of widely used free software licenses or copyleft that guarantee end users the four freedoms to run, study, share, and modify the software. The license was the first copyleft for general use and was originally written by Richard Stallman, the founder of the Free Software Foundation (FSF), for the GNU Project. The license grants the recipients of a computer program the rights of the Free Software Definition. These GPL series are all copyleft licenses, which means that any derivative work must be distributed under the same or equivalent license terms. It is more restrictive than the Lesser General Public License and even further distinct from the more widely used permissive software licenses BSD, MIT, and Apache.

<span class="mw-page-title-main">Linux kernel</span> Operating system kernel

The Linux kernel is a free and open-source, monolithic, modular, multitasking, Unix-like operating system kernel. It was originally written in 1991 by Linus Torvalds for his i386-based PC, and it was soon adopted as the kernel for the GNU operating system, which was written to be a free (libre) replacement for Unix.

The Android Native Development Kit (NDK) provides a cross-compiling tool for compiling code written in C/C++ can be compiled to ARM, or x86 native code (or their 64-bit variants) for Android. The NDK uses the Clang compiler to compile C/C++. GCC was included until NDK r17, but removed in r18 in 2018.

musl Implementation of C standard library for Linux operating system

musl is a C standard library intended for operating systems based on the Linux kernel, released under the MIT License. It was developed by Rich Felker with the goal to write a clean, efficient, and standards-conformant libc implementation.

Software relicensing is applied in open-source software development when software licenses of software modules are incompatible and are required to be compatible for a greater combined work. Licenses applied to software as copyrightable works, in source code as binary form, can contain contradictory clauses. These requirements can make it impossible to combine source code or content of several software works to create a new combined one.

References

  1. Burnette, Ed (June 4, 2008). "Patrick Brady dissects Android". ZDNet.
  2. Turner, David (2009-02-07). "Questions about Bionic". 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.
  3. Android Anatomy and Physiology (PDF), p. 36, archived from the original (PDF) on 2016-04-08, retrieved 2017-07-15, License: we want to keep GPL out of user-space
  4. Florian Mueller. "FOSS Patents".
  5. "Android 6.0 Compatibility Definition".
  6. "System hardening in Android 11". Android Developers Blog. Retrieved 2020-12-20.
  7. "Scudo". Android Open Source Project. Retrieved 2020-12-20.
  8. "Zygote". Anatomy of Android. Archived from the original on 2016-03-15. Retrieved 2016-03-14.
  9. "NDK Revision History | Android NDK".
  10. 1 2 "Android bionic status".
  11. Elliott Hughes. "libc: #define to remove support for %n from printf(3)?".
  12. "Android 4.2 Jelly Bean Release Notes". Android Developers. android.com. Retrieved 2013-12-27.
  13. "Android 4.2 and FORTIFY_SOURCE". Android Security Discussions. Retrieved 2013-12-27.
  14. "Android NDK changelog". Android NDK. android.googlesource.com. Retrieved 2017-08-28.
  15. "FORTIFY in Android". Android Developers Blog. android-developers.googleblog.com. Retrieved 2017-08-28.
  16. Google android and the linux headers on theregister.com (2011)
  17. 1 2 Android: Sued by Microsoft, not by Linux Archived 2016-01-13 at the Wayback Machine "Microsoft launches new Android suit, Linus Torvalds' take on Linux kernel headers and Android" on ITworld (March 21, 2011)
  18. Infringement and disclosure risk in development on copyleft platforms on ipinfoblog.com by Raymond Nimmer (2011)