# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import fnmatch
import glob
import logging
import os

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from optparse import OptionParser

FILE_CMD="file -m /usr/local/share/misc/magic.mgc"

class ToolchainOptionSet:
    """
    Handles a set of hits, along with potential whitelists to ignore.
    """
    def __init__(self, description, bad_files, whitelist_file):
        self.description = description
        self.bad_set = set(bad_files.splitlines())
        self.whitelist_set = set([])
        self.process_whitelist_with_private(whitelist_file)


    def process_whitelist_with_private(self, whitelist_file):
        """
        Filter out hits found on non-comment lines in the whitelist and
        and private whitelist.

        @param whitelist_file: path to whitelist file
        """
        whitelist_files = [whitelist_file]
        private_file = os.path.join(os.path.dirname(whitelist_file),
                                    "private_" +
                                    os.path.basename(whitelist_file))
        whitelist_files.append(private_file)
        self.process_whitelists(whitelist_files)


    def process_whitelist(self, whitelist_file):
        """
        Filter out hits found on non-comment lines in the whitelist.

        @param whitelist_file: path to whitelist file
        """
        if os.path.isfile(whitelist_file):
            f = open(whitelist_file)
            whitelist = [x for x in f.read().splitlines()
                                    if not x.startswith('#')]
            f.close()
            self.whitelist_set = self.whitelist_set.union(set(whitelist))

        filtered_list = []
        for bad_file in self.bad_set:
            # Does |bad_file| match any entry in the whitelist?
            in_whitelist = any([fnmatch.fnmatch(bad_file, whitelist_entry)
                                for whitelist_entry in self.whitelist_set])
            if not in_whitelist:
                filtered_list.append(bad_file)

        self.filtered_set = set(filtered_list)
        # TODO(jorgelo): remove glob patterns from |new_passes|.
        self.new_passes = self.whitelist_set.difference(self.bad_set)


    def process_whitelists(self, whitelist_files):
        """
        Filter out hits found in a list of whitelist files.

        @param whitelist_files: list of paths to whitelist files
        """
        for whitelist_file in whitelist_files:
            self.process_whitelist(whitelist_file)


    def get_fail_summary_message(self):
        m = "Test %s " % self.description
        m += "%d failures" % len(self.filtered_set)
        return m


    def get_fail_message(self):
        m = self.get_fail_summary_message()
        sorted_list = list(self.filtered_set)
        sorted_list.sort()
        m += "\nFAILED:\n%s\n\n" % "\n".join(sorted_list)
        return m


    def __str__(self):
        m = "Test %s " % self.description
        m += ("%d failures, %d in whitelist, %d in filtered, %d new passes " %
              (len(self.bad_set),
               len(self.whitelist_set),
               len(self.filtered_set),
               len(self.new_passes)))

        if len(self.filtered_set):
            sorted_list = list(self.filtered_set)
            sorted_list.sort()
            m += "FAILED:\n%s" % "\n".join(sorted_list)
        else:
            m += "PASSED!"

        if len(self.new_passes):
            sorted_list = list(self.new_passes)
            sorted_list.sort()
            m += ("\nNew passes (remove these from the whitelist):\n%s" %
                  "\n".join(sorted_list))
        logging.debug(m)
        return m


class platform_ToolchainOptions(test.test):
    """
    Tests for various expected conditions on ELF binaries in the image.
    """
    version = 2

    def get_cmd(self, test_cmd, find_options=""):
        base_cmd = ("find '%s' -wholename %s -prune -o "
                    " -wholename /proc -prune -o "
                    " -wholename /dev -prune -o "
                    " -wholename /sys -prune -o "
                    " -wholename /mnt/stateful_partition -prune -o "
                    " -wholename /usr/local -prune -o "
                    # There are files in /home (e.g. encrypted files that look
                    # like they have ELF headers) that cause false positives,
                    # and since that's noexec anyways, it should be skipped.
                    " -wholename '/home' -prune -o "
                    " -wholename "
                    "/opt/google/containers/android/rootfs/root/vendor"
                    " -prune -o "
                    " -wholename "
                    "/run/containers/android_*/root/vendor"
                    " -prune -o "
                    " %s "
                    " -not -name 'libstdc++.so.*' "
                    " -not -name 'libgcc_s.so.*' "
                    " -type f -executable -exec "
                    "sh -c '%s "
                    "{} | grep -q ELF && "
                    "(%s || echo {})' ';'")
        rootdir = "/"
        cmd = base_cmd % (rootdir, self.autodir, find_options, FILE_CMD,
                          test_cmd)
        return cmd


    def create_and_filter(self, description, cmd, whitelist_file,
                          find_options=""):
        """
        Runs a command, with "{}" replaced (via "find -exec") with the
        target ELF binary. If the command fails, the file is marked as
        failing the test. Results are filtered against the provided
        whitelist file.

        @param description: text name of the check being done
        @param cmd: command to run via find's -exec option
        @param whitelist_file: list of failures to ignore
        @param find_options: additional options for find to limit the scope
        """
        full_cmd = self.get_cmd(cmd, find_options)
        bad_files = utils.system_output(full_cmd)
        cso = ToolchainOptionSet(description, bad_files, whitelist_file)
        cso.process_whitelist_with_private(whitelist_file)
        return cso


    def run_once(self, rootdir="/", args=[]):
        """
        Do a find for all the ELF files on the system.
        For each one, test for compiler options that should have been used
        when compiling the file.

        For missing compiler options, print the files.
        """

        parser = OptionParser()
        parser.add_option('--hardfp',
                          dest='enable_hardfp',
                          default=False,
                          action='store_true',
                          help='Whether to check for hardfp binaries.')
        (options, args) = parser.parse_args(args)

        option_sets = []

        libc_glob = "/lib/libc-[0-9]*"

        readelf_cmd = glob.glob("/usr/local/*/binutils-bin/*/readelf")[0]

        # We do not test binaries if they are built with Address Sanitizer
        # because it is a separate testing tool.
        no_asan_used = utils.system_output("%s -s "
                                           "/opt/google/chrome/chrome | "
                                           "egrep -q \"__asan_init\" || "
                                           "echo no ASAN" % readelf_cmd)
        if not no_asan_used:
            logging.debug("ASAN detected on /opt/google/chrome/chrome. "
                          "Will skip all checks.")
            return

        # Check that gold was used to build binaries.
        # TODO(jorgelo): re-enable this check once crbug.com/417912 is fixed.
        # gold_cmd = ("%s -S {} 2>&1 | "
        #             "egrep -q \".note.gnu.gold-ve\"" % readelf_cmd)
        # gold_find_options = ""
        # if utils.get_cpu_arch() == "arm":
        #     # gold is only enabled for Chrome on ARM.
        #     gold_find_options = "-path \"/opt/google/chrome/chrome\""
        # gold_whitelist = os.path.join(self.bindir, "gold_whitelist")
        # option_sets.append(self.create_and_filter("gold",
        #                                           gold_cmd,
        #                                           gold_whitelist,
        #                                           gold_find_options))

        # Verify non-static binaries have BIND_NOW in dynamic section.
        now_cmd = ("(%s {} | grep -q statically) ||"
                   "%s -d {} 2>&1 | "
                   "egrep -q \"BIND_NOW\"" % (FILE_CMD, readelf_cmd))
        now_whitelist = os.path.join(self.bindir, "now_whitelist")
        option_sets.append(self.create_and_filter("-Wl,-z,now",
                                                  now_cmd,
                                                  now_whitelist))

        # Verify non-static binaries have RELRO program header.
        relro_cmd = ("(%s {} | grep -q statically) ||"
                     "%s -l {} 2>&1 | "
                     "egrep -q \"GNU_RELRO\"" % (FILE_CMD, readelf_cmd))
        relro_whitelist = os.path.join(self.bindir, "relro_whitelist")
        option_sets.append(self.create_and_filter("-Wl,-z,relro",
                                                  relro_cmd,
                                                  relro_whitelist))

        # Verify non-static binaries are dynamic (built PIE).
        pie_cmd = ("(%s {} | grep -q statically) ||"
                   "%s -l {} 2>&1 | "
                   "egrep -q \"Elf file type is DYN\"" % (FILE_CMD,
                                                          readelf_cmd))
        pie_whitelist = os.path.join(self.bindir, "pie_whitelist")
        option_sets.append(self.create_and_filter("-fPIE",
                                                  pie_cmd,
                                                  pie_whitelist))

        # Verify ELFs don't include TEXTRELs.
        # FIXME: Remove the i?86 filter after the bug is fixed.
        # crbug.com/686926
        if (utils.get_current_kernel_arch() not in
                ('i%d86' % i for i in xrange(3,7))):
            textrel_cmd = ("(%s {} | grep -q statically) ||"
                           "%s -d {} 2>&1 | "
                           "(egrep -q \"0x0+16..TEXTREL\"; [ $? -ne 0 ])"
                           % (FILE_CMD, readelf_cmd))
            textrel_whitelist = os.path.join(self.bindir, "textrel_whitelist")
            option_sets.append(self.create_and_filter("TEXTREL",
                                                      textrel_cmd,
                                                      textrel_whitelist))

        # Verify all binaries have non-exec STACK program header.
        stack_cmd = ("%s -lW {} 2>&1 | "
                     "egrep -q \"GNU_STACK.*RW \"" % readelf_cmd)
        stack_whitelist = os.path.join(self.bindir, "stack_whitelist")
        option_sets.append(self.create_and_filter("Executable Stack",
                                                  stack_cmd,
                                                  stack_whitelist))

        # Verify no binaries have W+X LOAD program headers.
        loadwx_cmd = ("%s -lW {} 2>&1 | "
                      "grep \"LOAD\" | egrep -v \"(RW |R E|R  )\" | "
                      "wc -l | grep -q \"^0$\"" % readelf_cmd)
        loadwx_whitelist = os.path.join(self.bindir, "loadwx_whitelist")
        option_sets.append(self.create_and_filter("LOAD Writable and Exec",
                                                  loadwx_cmd,
                                                  loadwx_whitelist))

        # Verify ARM binaries are all using VFP registers.
        if (options.enable_hardfp and utils.get_cpu_arch() == 'arm'):
            hardfp_cmd = ("%s -A {} 2>&1 | "
                          "egrep -q \"Tag_ABI_VFP_args: VFP registers\"" %
                          readelf_cmd)
            hardfp_whitelist = os.path.join(self.bindir, "hardfp_whitelist")
            option_sets.append(self.create_and_filter("hardfp", hardfp_cmd,
                                                      hardfp_whitelist))

        # Verify all binaries are not linked with libgcc_s.so.
        libgcc_cmd = ("%s -dW {} 2>&1 | grep \"NEEDED\" | "
                      "(! grep -q \"libgcc_s.so\")" % readelf_cmd)
        libgcc_whitelist = os.path.join(self.bindir, "libgcc_whitelist")
        option_sets.append(self.create_and_filter("Libgcc_s Users",
                                                  libgcc_cmd,
                                                  libgcc_whitelist))

        # Verify all binaries are not linked with libstdc++.so.
        libstdcxx_cmd = ("%s -dW {} 2>&1 | grep \"NEEDED\" | "
                         "(! grep -q \"libstdc++.so\")" % readelf_cmd)
        libstdcxx_whitelist = os.path.join(self.bindir, "libstdcxx_whitelist")
        option_sets.append(self.create_and_filter("Libstdc++ Users",
                                                  libstdcxx_cmd,
                                                  libstdcxx_whitelist))

        fail_msg = ""

        # There is currently no way to clear binary prebuilts for all devs.
        # Thus, when a new check is added to this test, the test might fail
        # for users who have old prebuilts which have not been compiled
        # in the correct manner.
        fail_summaries = []
        full_msg = "Test results:"
        num_fails = 0
        for cos in option_sets:
            if len(cos.filtered_set):
                num_fails += 1
                fail_msg += cos.get_fail_message() + "\n"
                fail_summaries.append(cos.get_fail_summary_message())
            full_msg += str(cos) + "\n\n"
        fail_summary_msg = ", ".join(fail_summaries)

        logging.error(fail_msg)
        logging.debug(full_msg)
        if num_fails:
            raise error.TestFail(fail_summary_msg)
