#!/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"]
        build_path =  android_build_top_path + "/bionic/libc"
        file_name = "libgcc_compat.c"
        file_path = build_path + "/arch-arm/bionic/" + file_name

        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':
            sys.exit("Error: Invalid TARGET_ARCH='" + arch + "' expecting 'arm'")

        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()

