#!/usr/bin/python

'''
/* This file generates libgcc_compat.c file that 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.
 */
'''

import os
import sys
import subprocess
import tempfile
import re

libgcc_compat_header = "/* Generated by genlibgcc_compat.py */\n\n"

class Generator:
    def process(self):
        android_build_top_path = os.environ["ANDROID_BUILD_TOP"]

        print "* ANDROID_BUILD_TOP=" + android_build_top_path

        # Check TARGET_ARCH
        arch = subprocess.check_output(["CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make --no-print-directory -f build/core/config.mk dumpvar-TARGET_ARCH"],
                    cwd=android_build_top_path, shell=True).strip()

        if arch != 'arm' and arch != 'x86':
            sys.exit("Error: Invalid TARGET_ARCH='" + arch + "' expecting 'arm' or 'x86'")

        build_path =  android_build_top_path + "/bionic/libc"
        file_name = "libgcc_compat.c"
        file_path = build_path + "/arch-" + arch + "/bionic/" + file_name

        build_output_file_path = tempfile.mkstemp()[1]

        p = subprocess.Popen(["ONE_SHOT_MAKEFILE=bionic/libc/Android.mk make -C " + android_build_top_path
                    + " -f build/core/main.mk all_modules TARGET_LIBGCC= -j20 -B 2>&1 | tee " + build_output_file_path],
                    cwd=build_path, shell=True)
        p.wait()

        print "* Build complete, logfile: " + build_output_file_path

        symbol_set = set()
        prog=re.compile("(?<=undefined reference to ')\w+")
        fd = open(build_output_file_path, 'r')
        for line in fd:
            m = prog.search(line)
            if m:
                symbol_set.add(m.group(0))

        fd.close()

        symbol_list = sorted(symbol_set)

        print "* Found " + repr(len(symbol_list)) + " referenced symbols: " + repr(symbol_list)

        if 0 == len(symbol_list):
            sys.exit("Error: symbol list is empty, please check the build log: " + build_output_file_path)

        print "* Generating " + file_path
        fres = open(file_path, 'w')
        fres.write(libgcc_compat_header)

        for sym_name in symbol_list:
            fres.write("extern char "+sym_name+";\n")
        fres.write("\n");

        fres.write("void* __bionic_libgcc_compat_symbols[] = {\n");
        for sym_name in symbol_list:
            fres.write("    &"+sym_name+",\n")
        fres.write("};\n");

        fres.close()

generator = Generator()
generator.process()

