#!/usr/bin/env python
#
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

#
# Dump the contents of the .note.android.ident section, a NOTE section
# embedded into Android binaries. See here:
#  - master: ndk/sources/crt/crtbrand.S
#  - master: bionic/libc/arch-common/bionic/crtbrand.S
#  - NDK before r14: development/ndk/platforms/common/src/crtbrand.c
#
# Note sections can also be dumped with `readelf -n`.
#

from __future__ import division, print_function
import argparse
import logging
import struct
import subprocess
import sys

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

SEC_NAME = '.note.android.ident'
NDK_RESERVED_SIZE = 64


def logger():
    """Returns the module logger."""
    return logging.getLogger(__name__)


def round_up_to_nearest(val, step):
    """Round an integer, val, to the next multiple of a positive integer,
    step."""
    return (val + (step - 1)) // step * step


class StructParser(object):
    def __init__(self, buf):
        self._sio = StringIO(buf)

    @property
    def _remaining(self):
        return self._sio.len - self._sio.pos

    @property
    def empty(self):
        return self._remaining == 0

    def read_struct(self, fmt, kind):
        fmt = struct.Struct(fmt)
        if self._remaining < fmt.size:
            sys.exit('error: {} was truncated'.format(kind))
        return fmt.unpack(self._sio.read(fmt.size))


def iterate_notes(sec_data):
    sec_data = StructParser(sec_data)
    while not sec_data.empty:
        (namesz, descsz, kind) = sec_data.read_struct('<III', 'note header')
        (name, desc) = sec_data.read_struct(
            '{}s{}s'.format(
                round_up_to_nearest(namesz, 4),
                round_up_to_nearest(descsz, 4)),
            'note body')
        name = name[:namesz]
        if len(name) > 0:
            if name[-1:] == '\0':
                name = name[:-1]
            else:
                logger().warning('note name %s isn\'t NUL-terminated', name)
        yield name, kind, desc[:descsz]


def dump_android_ident_note(note):
    note = StructParser(note)
    (android_api,) = note.read_struct('<I', 'note descriptor')
    print('ABI_ANDROID_API: {}'.format(android_api))
    if note.empty:
        return
    # Binaries generated by NDK r14 and later have these extra fields. Platform
    # binaries and binaries generated by older NDKs don't.
    (ndk_version, ndk_build_number) = note.read_struct(
        '{}s{}s'.format(NDK_RESERVED_SIZE, NDK_RESERVED_SIZE),
        'note descriptor')
    print('ABI_NDK_VERSION: {}'.format(ndk_version.rstrip('\0')))
    print('ABI_NDK_BUILD_NUMBER: {}'.format(ndk_build_number.rstrip('\0')))
    if not note.empty:
        logger().warning('excess data at end of descriptor')


# Get the offset to a section from the output of readelf
def get_section_pos(sec_name, file_path):
    cmd = ['readelf', '--sections', '-W', file_path]
    output = subprocess.check_output(cmd)
    lines = output.splitlines()
    for line in lines:
        logger().debug('Checking line for "%s": %s', sec_name, line)
        # Looking for a line like the following (all whitespace of unknown
        # width).
        #
        #   [ 8] .note.android.ident NOTE 00000000 0000ec 000098 00 A 0 0 4
        #
        # The only column that might have internal whitespace is the first one.
        # Since we don't care about it, remove the head of the string until the
        # closing bracket, then split.
        if ']' not in line:
            continue
        line = line[line.index(']') + 1:]

        sections = line.split()
        if len(sections) < 5 or sec_name != sections[0]:
            continue
        off = int(sections[3], 16)
        size = int(sections[4], 16)
        return (off, size)
    sys.exit('error: failed to find section: {}'.format(sec_name))


def parse_args():
    """Parses command line arguments."""
    parser = argparse.ArgumentParser()
    parser.add_argument('file_path',
                        help="path of the ELF file with embedded ABI tags")
    parser.add_argument(
        '-v', '--verbose', dest='verbosity', action='count', default=0,
        help='Increase logging verbosity.')
    return parser.parse_args()


def main():
    args = parse_args()
    if args.verbosity == 1:
        logging.basicConfig(level=logging.INFO)
    elif args.verbosity >= 2:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig()

    file_path = args.file_path

    with open(file_path, "rb") as obj_file:
        (sec_off, sec_size) = get_section_pos(SEC_NAME, file_path)

        obj_file.seek(sec_off)
        sec_data = obj_file.read(sec_size)
        if len(sec_data) != sec_size:
            sys.exit('error: could not read {} section'.format(SEC_NAME))

        print('----------ABI INFO----------')
        if len(sec_data) == 0:
            logger().warning('%s section is empty', SEC_NAME)
        for (name, kind, desc) in iterate_notes(sec_data):
            if (name, kind) == ('Android', 1):
                dump_android_ident_note(desc)
            else:
                logger().warning('unrecognized note (name %s, type %d)',
                                 repr(name), kind)


if __name__ == '__main__':
    main()
