| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| */ |
| |
| /* This file contains dummy references to libgcc.a functions to force the |
| * dynamic linker to copy their definition into the final libc.so binary. |
| * |
| * They are required to ensure backwards binary compatibility with |
| * libc.so provided by the platform and binaries built with the NDK or |
| * different versions/configurations of toolchains. |
| * |
| * Now, for a more elaborate description of the issue: |
| * |
| * libgcc.a is a compiler-specific library containing various helper |
| * functions used to implement certain operations that are not necessarily |
| * supported by the target CPU. For example, integer division doesn't have a |
| * corresponding CPU instruction on ARMv5, and is instead implemented in the |
| * compiler-generated machine code as a call to an __idiv helper function. |
| * |
| * Normally, one has to place libgcc.a in the link command used to generate |
| * target binaries (shared libraries and executables) after all objects and |
| * static libraries, but before dependent shared libraries, i.e. something |
| * like: |
| * gcc <options> -o libfoo.so foo.a libgcc.a -lc -lm |
| * |
| * This ensures that any helper function needed by the code in foo.a is copied |
| * into the final libfoo.so. However, doing so will link a bunch of other __cxa |
| * functions from libgcc.a into each .so and executable, causing 4k+ increase |
| * in every binary. Therefore the Android platform build system has been |
| * using this instead: |
| * |
| * gcc <options> -o libfoo.so foo.a -lc -lm libgcc.a |
| * |
| * The problem with this is that if one helper function needed by foo.a has |
| * already been copied into libc.so or libm.so, then nothing will be copied |
| * into libfoo.so. Instead, a symbol import definition will be added to it |
| * so libfoo.so can directly call the one in libc.so at runtime. |
| * |
| * When refreshing toolchains for new versions or using different architecture |
| * flags, the set of helper functions copied to libc.so may change, which |
| * resulted in some native shared libraries generated with the NDK or prebuilts |
| * from vendors to fail to load properly. |
| * |
| * The NDK has been fixed after 1.6_r1 to use the correct link command, so |
| * any native shared library generated with it should now be safe from that |
| * problem. On the other hand, existing shared libraries distributed with |
| * applications that were generated with a previous version of the NDK |
| * still need all 1.5/1.6 helper functions in libc.so and libm.so |
| * |
| * After 3.2, the toolchain was updated again, adding __aeabi_f2uiz to the |
| * list of requirements. Technically, this is due to mis-linked NDK libraries |
| * but it is easier to add a single function here than asking several app |
| * developers to fix their build. |
| * |
| * The __aeabi_idiv function is added to the list since cortex-a15 supports |
| * HW idiv instructions so the system libc.so doesn't pull in the reference to |
| * __aeabi_idiv but legacy libraries built against cortex-a9 targets still need |
| * it. |
| * |
| * Final note: some of the functions below should really be in libm.so to |
| * completely reflect the state of 1.5/1.6 system images. However, |
| * since libm.so depends on libc.so, it's easier to put all of |
| * these in libc.so instead, since the dynamic linker will always |
| * search in libc.so before libm.so for dependencies. |
| */ |
| |
| #define COMPAT_FUNCTIONS_LIST \ |
| XX(__adddf3) \ |
| XX(__addsf3) \ |
| XX(__aeabi_cdcmpeq) \ |
| XX(__aeabi_cdcmple) \ |
| XX(__aeabi_cdrcmple) \ |
| XX(__aeabi_d2f) \ |
| XX(__aeabi_d2iz) \ |
| XX(__aeabi_dadd) \ |
| XX(__aeabi_dcmpeq) \ |
| XX(__aeabi_dcmpge) \ |
| XX(__aeabi_dcmpgt) \ |
| XX(__aeabi_dcmple) \ |
| XX(__aeabi_dcmplt) \ |
| XX(__aeabi_dcmpun) \ |
| XX(__aeabi_ddiv) \ |
| XX(__aeabi_dmul) \ |
| XX(__aeabi_drsub) \ |
| XX(__aeabi_dsub) \ |
| XX(__aeabi_f2d) \ |
| XX(__aeabi_f2iz) \ |
| XX(__aeabi_f2uiz) \ |
| XX(__aeabi_fadd) \ |
| XX(__aeabi_fcmpun) \ |
| XX(__aeabi_fdiv) \ |
| XX(__aeabi_fmul) \ |
| XX(__aeabi_frsub) \ |
| XX(__aeabi_fsub) \ |
| XX(__aeabi_i2d) \ |
| XX(__aeabi_i2f) \ |
| XX(__aeabi_idiv) \ |
| XX(__aeabi_idivmod) \ |
| XX(__aeabi_l2d) \ |
| XX(__aeabi_l2f) \ |
| XX(__aeabi_lasr) \ |
| XX(__aeabi_ldivmod) \ |
| XX(__aeabi_llsl) \ |
| XX(__aeabi_llsr) \ |
| XX(__aeabi_lmul) \ |
| XX(__aeabi_ui2d) \ |
| XX(__aeabi_ui2f) \ |
| XX(__aeabi_uidiv) \ |
| XX(__aeabi_uidivmod) \ |
| XX(__aeabi_ul2d) \ |
| XX(__aeabi_ul2f) \ |
| XX(__aeabi_uldivmod) \ |
| XX(__cmpdf2) \ |
| XX(__divdf3) \ |
| XX(__divsf3) \ |
| XX(__eqdf2) \ |
| XX(__extendsfdf2) \ |
| XX(__fixdfsi) \ |
| XX(__fixsfsi) \ |
| XX(__floatdidf) \ |
| XX(__floatdisf) \ |
| XX(__floatsidf) \ |
| XX(__floatsisf) \ |
| XX(__floatundidf) \ |
| XX(__floatundisf) \ |
| XX(__floatunsidf) \ |
| XX(__floatunsisf) \ |
| XX(__gedf2) \ |
| XX(__gtdf2) \ |
| XX(__ledf2) \ |
| XX(__ltdf2) \ |
| XX(__muldf3) \ |
| XX(__muldi3) \ |
| XX(__mulsf3) \ |
| XX(__nedf2) \ |
| XX(__popcountsi2) \ |
| XX(__popcount_tab) \ |
| XX(__subdf3) \ |
| XX(__subsf3) \ |
| XX(__truncdfsf2) \ |
| XX(__unorddf2) \ |
| XX(__unordsf2) \ |
| |
| #define XX(f) extern void f(void); |
| COMPAT_FUNCTIONS_LIST |
| #undef XX |
| |
| void __bionic_libgcc_compat_hooks(void) |
| { |
| #define XX(f) f(); |
| COMPAT_FUNCTIONS_LIST |
| #undef XX |
| } |