David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2008 The Android Open Source Project |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * * Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * * Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in |
| 12 | * the documentation and/or other materials provided with the |
| 13 | * distribution. |
| 14 | * |
| 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 26 | * SUCH DAMAGE. |
| 27 | */ |
| 28 | |
| 29 | /* This file contains dummy references to libgcc.a functions to force the |
| 30 | * dynamic linker to copy their definition into the final libc.so binary. |
| 31 | * |
| 32 | * They are required to ensure backwards binary compatibility with |
Ben Cheng | 772b797 | 2013-08-02 15:33:27 -0700 | [diff] [blame] | 33 | * libc.so provided by the platform and binaries built with the NDK or |
| 34 | * different versions/configurations of toolchains. |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 35 | * |
| 36 | * Now, for a more elaborate description of the issue: |
| 37 | * |
| 38 | * libgcc.a is a compiler-specific library containing various helper |
| 39 | * functions used to implement certain operations that are not necessarily |
| 40 | * supported by the target CPU. For example, integer division doesn't have a |
| 41 | * corresponding CPU instruction on ARMv5, and is instead implemented in the |
| 42 | * compiler-generated machine code as a call to an __idiv helper function. |
| 43 | * |
| 44 | * Normally, one has to place libgcc.a in the link command used to generate |
| 45 | * target binaries (shared libraries and executables) after all objects and |
| 46 | * static libraries, but before dependent shared libraries, i.e. something |
| 47 | * like: |
| 48 | * gcc <options> -o libfoo.so foo.a libgcc.a -lc -lm |
| 49 | * |
| 50 | * This ensures that any helper function needed by the code in foo.a is copied |
Ben Cheng | 772b797 | 2013-08-02 15:33:27 -0700 | [diff] [blame] | 51 | * into the final libfoo.so. However, doing so will link a bunch of other __cxa |
| 52 | * functions from libgcc.a into each .so and executable, causing 4k+ increase |
| 53 | * in every binary. Therefore the Android platform build system has been |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 54 | * using this instead: |
| 55 | * |
| 56 | * gcc <options> -o libfoo.so foo.a -lc -lm libgcc.a |
| 57 | * |
| 58 | * The problem with this is that if one helper function needed by foo.a has |
| 59 | * already been copied into libc.so or libm.so, then nothing will be copied |
| 60 | * into libfoo.so. Instead, a symbol import definition will be added to it |
| 61 | * so libfoo.so can directly call the one in libc.so at runtime. |
| 62 | * |
Ben Cheng | 772b797 | 2013-08-02 15:33:27 -0700 | [diff] [blame] | 63 | * When refreshing toolchains for new versions or using different architecture |
| 64 | * flags, the set of helper functions copied to libc.so may change, which |
| 65 | * resulted in some native shared libraries generated with the NDK or prebuilts |
| 66 | * from vendors to fail to load properly. |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 67 | * |
| 68 | * The NDK has been fixed after 1.6_r1 to use the correct link command, so |
| 69 | * any native shared library generated with it should now be safe from that |
| 70 | * problem. On the other hand, existing shared libraries distributed with |
| 71 | * applications that were generated with a previous version of the NDK |
Andrew Hsieh | 58b2c16 | 2012-02-21 15:09:32 -0800 | [diff] [blame] | 72 | * still need all 1.5/1.6 helper functions in libc.so and libm.so |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 73 | * |
David 'Digit' Turner | 58246b7 | 2011-08-22 19:50:51 +0200 | [diff] [blame] | 74 | * After 3.2, the toolchain was updated again, adding __aeabi_f2uiz to the |
| 75 | * list of requirements. Technically, this is due to mis-linked NDK libraries |
| 76 | * but it is easier to add a single function here than asking several app |
| 77 | * developers to fix their build. |
| 78 | * |
Ben Cheng | 772b797 | 2013-08-02 15:33:27 -0700 | [diff] [blame] | 79 | * The __aeabi_idiv function is added to the list since cortex-a15 supports |
| 80 | * HW idiv instructions so the system libc.so doesn't pull in the reference to |
| 81 | * __aeabi_idiv but legacy libraries built against cortex-a9 targets still need |
| 82 | * it. |
| 83 | * |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 84 | * Final note: some of the functions below should really be in libm.so to |
| 85 | * completely reflect the state of 1.5/1.6 system images. However, |
| 86 | * since libm.so depends on libc.so, it's easier to put all of |
| 87 | * these in libc.so instead, since the dynamic linker will always |
| 88 | * search in libc.so before libm.so for dependencies. |
| 89 | */ |
| 90 | |
| 91 | #define COMPAT_FUNCTIONS_LIST \ |
| 92 | XX(__adddf3) \ |
| 93 | XX(__addsf3) \ |
| 94 | XX(__aeabi_cdcmpeq) \ |
| 95 | XX(__aeabi_cdcmple) \ |
| 96 | XX(__aeabi_cdrcmple) \ |
| 97 | XX(__aeabi_d2f) \ |
| 98 | XX(__aeabi_d2iz) \ |
| 99 | XX(__aeabi_dadd) \ |
| 100 | XX(__aeabi_dcmpeq) \ |
| 101 | XX(__aeabi_dcmpge) \ |
| 102 | XX(__aeabi_dcmpgt) \ |
| 103 | XX(__aeabi_dcmple) \ |
| 104 | XX(__aeabi_dcmplt) \ |
| 105 | XX(__aeabi_dcmpun) \ |
| 106 | XX(__aeabi_ddiv) \ |
| 107 | XX(__aeabi_dmul) \ |
| 108 | XX(__aeabi_drsub) \ |
| 109 | XX(__aeabi_dsub) \ |
| 110 | XX(__aeabi_f2d) \ |
| 111 | XX(__aeabi_f2iz) \ |
David 'Digit' Turner | 58246b7 | 2011-08-22 19:50:51 +0200 | [diff] [blame] | 112 | XX(__aeabi_f2uiz) \ |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 113 | XX(__aeabi_fadd) \ |
| 114 | XX(__aeabi_fcmpun) \ |
| 115 | XX(__aeabi_fdiv) \ |
| 116 | XX(__aeabi_fmul) \ |
| 117 | XX(__aeabi_frsub) \ |
| 118 | XX(__aeabi_fsub) \ |
| 119 | XX(__aeabi_i2d) \ |
| 120 | XX(__aeabi_i2f) \ |
Ben Cheng | a4e964d | 2013-01-14 11:26:51 -0800 | [diff] [blame] | 121 | XX(__aeabi_idiv) \ |
Ben Cheng | 62ffe14 | 2014-01-24 15:20:11 -0800 | [diff] [blame] | 122 | XX(__aeabi_idivmod) \ |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 123 | XX(__aeabi_l2d) \ |
| 124 | XX(__aeabi_l2f) \ |
synergydev | efddf44 | 2013-07-28 21:43:00 +0000 | [diff] [blame] | 125 | XX(__aeabi_lasr) \ |
Ben Cheng | 62ffe14 | 2014-01-24 15:20:11 -0800 | [diff] [blame] | 126 | XX(__aeabi_ldivmod) \ |
Dima Zavin | f1a17e7 | 2012-02-22 15:18:54 -0800 | [diff] [blame] | 127 | XX(__aeabi_llsl) \ |
| 128 | XX(__aeabi_llsr) \ |
Ben Cheng | 62ffe14 | 2014-01-24 15:20:11 -0800 | [diff] [blame] | 129 | XX(__aeabi_lmul) \ |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 130 | XX(__aeabi_ui2d) \ |
| 131 | XX(__aeabi_ui2f) \ |
Ben Cheng | 62ffe14 | 2014-01-24 15:20:11 -0800 | [diff] [blame] | 132 | XX(__aeabi_uidiv) \ |
| 133 | XX(__aeabi_uidivmod) \ |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 134 | XX(__aeabi_ul2d) \ |
| 135 | XX(__aeabi_ul2f) \ |
Ben Cheng | 62ffe14 | 2014-01-24 15:20:11 -0800 | [diff] [blame] | 136 | XX(__aeabi_uldivmod) \ |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 137 | XX(__cmpdf2) \ |
| 138 | XX(__divdf3) \ |
| 139 | XX(__divsf3) \ |
synergydev | efddf44 | 2013-07-28 21:43:00 +0000 | [diff] [blame] | 140 | XX(__eqdf2) \ |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 141 | XX(__extendsfdf2) \ |
| 142 | XX(__fixdfsi) \ |
| 143 | XX(__fixsfsi) \ |
| 144 | XX(__floatdidf) \ |
| 145 | XX(__floatdisf) \ |
| 146 | XX(__floatsidf) \ |
| 147 | XX(__floatsisf) \ |
| 148 | XX(__floatundidf) \ |
| 149 | XX(__floatundisf) \ |
| 150 | XX(__floatunsidf) \ |
| 151 | XX(__floatunsisf) \ |
| 152 | XX(__gedf2) \ |
| 153 | XX(__gtdf2) \ |
| 154 | XX(__ledf2) \ |
| 155 | XX(__ltdf2) \ |
| 156 | XX(__muldf3) \ |
| 157 | XX(__muldi3) \ |
| 158 | XX(__mulsf3) \ |
| 159 | XX(__nedf2) \ |
Ben Cheng | e3fb66d | 2013-12-19 16:26:40 -0800 | [diff] [blame] | 160 | XX(__popcountsi2) \ |
Bernhard Rosenkränzer | f38fb19 | 2014-01-24 12:55:00 +0100 | [diff] [blame] | 161 | XX(__popcount_tab) \ |
David 'Digit' Turner | 2a7ad97 | 2009-09-29 14:43:38 -0700 | [diff] [blame] | 162 | XX(__subdf3) \ |
| 163 | XX(__subsf3) \ |
| 164 | XX(__truncdfsf2) \ |
| 165 | XX(__unorddf2) \ |
| 166 | XX(__unordsf2) \ |
| 167 | |
| 168 | #define XX(f) extern void f(void); |
| 169 | COMPAT_FUNCTIONS_LIST |
| 170 | #undef XX |
| 171 | |
| 172 | void __bionic_libgcc_compat_hooks(void) |
| 173 | { |
| 174 | #define XX(f) f(); |
| 175 | COMPAT_FUNCTIONS_LIST |
| 176 | #undef XX |
| 177 | } |