#!/usr/bin/env python3
#
# Copyright 2018, 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.

"""Unpacks the boot image.

Extracts the kernel, ramdisk, second bootloader, dtb and recovery dtbo images.
"""

from argparse import ArgumentParser, FileType, RawDescriptionHelpFormatter
from struct import unpack
import json
import os
import shlex

BOOT_IMAGE_HEADER_V3_PAGESIZE = 4096
VENDOR_RAMDISK_NAME_SIZE = 32
VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE = 16

MKBOOTIMG_ARGS_FILE = 'mkbootimg_args.json'


def create_out_dir(dir_path):
    """creates a directory 'dir_path' if it does not exist"""
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)


def extract_image(offset, size, bootimage, extracted_image_name):
    """extracts an image from the bootimage"""
    bootimage.seek(offset)
    with open(extracted_image_name, 'wb') as file_out:
        file_out.write(bootimage.read(size))


def get_number_of_pages(image_size, page_size):
    """calculates the number of pages required for the image"""
    return (image_size + page_size - 1) // page_size


def cstr(s):
    """Remove first NULL character and any character beyond."""
    return s.split('\0', 1)[0]


def format_os_version(os_version):
    a = os_version >> 14
    b = os_version >> 7 & ((1<<7) - 1)
    c = os_version & ((1<<7) - 1)
    return '{}.{}.{}'.format(a, b, c)


def format_os_patch_level(os_patch_level):
    y = os_patch_level >> 4
    y += 2000
    m = os_patch_level & ((1<<4) - 1)
    return '{:04d}-{:02d}'.format(y, m)


def print_os_version_patch_level(value):
    os_version = value >> 11
    os_patch_level = value & ((1<<11) - 1)
    print('os version: %s' % format_os_version(os_version))
    print('os patch level: %s' % format_os_patch_level(os_patch_level))


def decode_os_version_patch_level(os_version_patch_level):
    """Returns a tuple of (os_version, os_patch_level)."""
    os_version = os_version_patch_level >> 11
    os_patch_level = os_version_patch_level & ((1<<11) - 1)
    return (format_os_version(os_version),
            format_os_patch_level(os_patch_level))


def get_boot_image_v2_and_below_args(header_version, page_size,
                                     kernel_load_address, ramdisk_load_address,
                                     second_load_address, tags_load_address,
                                     dtb_load_address, cmdline, extra_cmdline,
                                     os_version_patch_level, product_name):
    """Returns a dict of mkbootimg.py arguments for v0, v1 and v2 boot.img."""
    mkbootimg_args = {}
    mkbootimg_args['header_version'] = str(header_version)
    # The type of pagesize is uint32_t, using '0xFFFFFFFF' as the output format.
    mkbootimg_args['pagesize'] = '{:#010x}'.format(page_size)

    # Kernel load address is base + kernel_offset in mkbootimg.py.
    # However, we don't know the value of 'base' when unpack a boot.img
    # in this script. So always set 'base' to be zero and 'kernel_offset' to
    # be the kernel load address. Same for 'ramdisk_offset', 'second_offset',
    # 'tags_offset' and 'dtb_offset'.
    # The following types are uint32_t, using '0xFFFFFFFF' as the output format.
    mkbootimg_args['base'] = '{:#010x}'.format(0)
    mkbootimg_args['kernel_offset'] = '{:#010x}'.format(kernel_load_address)
    mkbootimg_args['ramdisk_offset'] = '{:#010x}'.format(ramdisk_load_address)
    mkbootimg_args['second_offset'] = '{:#010x}'.format(second_load_address)
    mkbootimg_args['tags_offset'] = '{:#010x}'.format(tags_load_address)

    # dtb is added in boot image v2, and is absent in v1 or v0.
    if header_version == 2:
        # The type of dtb_offset is uint64_t, using '0xFFFFFFFFEEEEEEEE' as
        # the output format.
        mkbootimg_args['dtb_offset'] = '{:#018x}'.format(dtb_load_address)

    mkbootimg_args['os_version'], mkbootimg_args['os_patch_level'] = (
        decode_os_version_patch_level(os_version_patch_level))

    mkbootimg_args['cmdline'] = cmdline + extra_cmdline
    mkbootimg_args['board'] = product_name

    return mkbootimg_args


def get_boot_image_v3_args(header_version, os_version_patch_level, cmdline):
    """Returns a dict of arguments to be used in mkbootimg.py later."""
    mkbootimg_args = {}
    mkbootimg_args['header_version'] = str(header_version)
    mkbootimg_args['os_version'], mkbootimg_args['os_patch_level'] = (
        decode_os_version_patch_level(os_version_patch_level))
    mkbootimg_args['cmdline'] = cmdline

    return mkbootimg_args


def unpack_boot_image(args):
    """extracts kernel, ramdisk, second bootloader and recovery dtbo"""
    boot_magic = unpack('8s', args.boot_img.read(8))[0].decode()
    print('boot_magic: %s' % boot_magic)
    # TODO(yochiang): Support --format=mkbootimg

    kernel_ramdisk_second_info = unpack('9I', args.boot_img.read(9 * 4))

    # version is always at [8] regardless of version.
    version = kernel_ramdisk_second_info[8]

    if version < 3:
        kernel_size = kernel_ramdisk_second_info[0]
        kernel_load_address = kernel_ramdisk_second_info[1]
        ramdisk_size = kernel_ramdisk_second_info[2]
        ramdisk_load_address = kernel_ramdisk_second_info[3]
        second_size = kernel_ramdisk_second_info[4]
        second_load_address = kernel_ramdisk_second_info[5]
        tags_load_address = kernel_ramdisk_second_info[6]
        page_size = kernel_ramdisk_second_info[7]
        os_version_patch_level = unpack('I', args.boot_img.read(1 * 4))[0]
    else:
        kernel_size = kernel_ramdisk_second_info[0]
        ramdisk_size = kernel_ramdisk_second_info[1]
        os_version_patch_level = kernel_ramdisk_second_info[2]
        second_size = 0
        page_size = BOOT_IMAGE_HEADER_V3_PAGESIZE

    if version < 3:
        print('kernel_size: %s' % kernel_size)
        print('kernel load address: %#x' % kernel_load_address)
        print('ramdisk size: %s' % ramdisk_size)
        print('ramdisk load address: %#x' % ramdisk_load_address)
        print('second bootloader size: %s' % second_size)
        print('second bootloader load address: %#x' % second_load_address)
        print('kernel tags load address: %#x' % tags_load_address)
        print('page size: %s' % page_size)
        print_os_version_patch_level(os_version_patch_level)
    else:
        print('kernel_size: %s' % kernel_size)
        print('ramdisk size: %s' % ramdisk_size)
        print_os_version_patch_level(os_version_patch_level)

    print('boot image header version: %s' % version)

    if version < 3:
        product_name = cstr(unpack('16s', args.boot_img.read(16))[0].decode())
        print('product name: %s' % product_name)
        cmdline = cstr(unpack('512s', args.boot_img.read(512))[0].decode())
        print('command line args: %s' % cmdline)
    else:
        cmdline = cstr(unpack('1536s', args.boot_img.read(1536))[0].decode())
        print('command line args: %s' % cmdline)

    if version < 3:
        args.boot_img.read(32)  # ignore SHA

    if version < 3:
        extra_cmdline = cstr(unpack('1024s',
                                    args.boot_img.read(1024))[0].decode())
        print('additional command line args: %s' % extra_cmdline)

    if 0 < version < 3:
        recovery_dtbo_size = unpack('I', args.boot_img.read(1 * 4))[0]
        print('recovery dtbo size: %s' % recovery_dtbo_size)
        recovery_dtbo_offset = unpack('Q', args.boot_img.read(8))[0]
        print('recovery dtbo offset: %#x' % recovery_dtbo_offset)
        boot_header_size = unpack('I', args.boot_img.read(4))[0]
        print('boot header size: %s' % boot_header_size)
    else:
        recovery_dtbo_size = 0

    if 1 < version < 3:
        dtb_size = unpack('I', args.boot_img.read(4))[0]
        print('dtb size: %s' % dtb_size)
        dtb_load_address = unpack('Q', args.boot_img.read(8))[0]
        print('dtb address: %#x' % dtb_load_address)
    else:
        dtb_size = 0
        dtb_load_address = 0

    # Saves the arguments to be reused in mkbootimg.py later.
    if version < 3:
        mkbootimg_args = get_boot_image_v2_and_below_args(
            version, page_size, kernel_load_address, ramdisk_load_address,
            second_load_address, tags_load_address, dtb_load_address, cmdline,
            extra_cmdline, os_version_patch_level, product_name)
    else:
        mkbootimg_args = get_boot_image_v3_args(
            version, os_version_patch_level, cmdline)
    with open(os.path.join(args.out, MKBOOTIMG_ARGS_FILE), 'w') as f:
        json.dump(mkbootimg_args, f, sort_keys=True, indent=4)

    if version >= 4:
        boot_signature_size = unpack('I', args.boot_img.read(4))[0]
        print('boot.img signature size: %s' % boot_signature_size)
    else:
        boot_signature_size = 0

    # The first page contains the boot header
    num_header_pages = 1

    num_kernel_pages = get_number_of_pages(kernel_size, page_size)
    kernel_offset = page_size * num_header_pages  # header occupies a page
    image_info_list = [(kernel_offset, kernel_size, 'kernel')]

    num_ramdisk_pages = get_number_of_pages(ramdisk_size, page_size)
    ramdisk_offset = page_size * (num_header_pages + num_kernel_pages
                                 ) # header + kernel
    image_info_list.append((ramdisk_offset, ramdisk_size, 'ramdisk'))

    if second_size > 0:
        second_offset = page_size * (
            num_header_pages + num_kernel_pages + num_ramdisk_pages
            )  # header + kernel + ramdisk
        image_info_list.append((second_offset, second_size, 'second'))

    if recovery_dtbo_size > 0:
        image_info_list.append((recovery_dtbo_offset, recovery_dtbo_size,
                                'recovery_dtbo'))
    if dtb_size > 0:
        num_second_pages = get_number_of_pages(second_size, page_size)
        num_recovery_dtbo_pages = get_number_of_pages(
            recovery_dtbo_size, page_size)
        dtb_offset = page_size * (
            num_header_pages + num_kernel_pages + num_ramdisk_pages +
            num_second_pages + num_recovery_dtbo_pages)

        image_info_list.append((dtb_offset, dtb_size, 'dtb'))

    if boot_signature_size > 0:
        # boot signature only exists in boot.img version >= v4.
        # There are only kernel and ramdisk pages before the signature.
        boot_signature_offset = page_size * (
            num_header_pages + num_kernel_pages + num_ramdisk_pages)

        image_info_list.append((boot_signature_offset, boot_signature_size,
                                'boot_signature'))

    for image_info in image_info_list:
        extract_image(image_info[0], image_info[1], args.boot_img,
                      os.path.join(args.out, image_info[2]))


class VendorBootImageInfoFormatter:
    """Formats the vendor_boot image info."""

    def format_pretty_text(self):
        lines = []
        lines.append(f'boot magic: {self.boot_magic}')
        lines.append(f'vendor boot image header version: {self.header_version}')
        lines.append(f'page size: {self.page_size:#010x}')
        lines.append(f'kernel load address: {self.kernel_load_address:#010x}')
        lines.append(f'ramdisk load address: {self.ramdisk_load_address:#010x}')
        if self.header_version > 3:
            lines.append(
                f'vendor ramdisk total size: {self.vendor_ramdisk_size}')
        else:
            lines.append(f'vendor ramdisk size: {self.vendor_ramdisk_size}')
        lines.append(f'vendor command line args: {self.cmdline}')
        lines.append(
            f'kernel tags load address: {self.tags_load_address:#010x}')
        lines.append(f'product name: {self.product_name}')
        lines.append(f'vendor boot image header size: {self.header_size}')
        lines.append(f'dtb size: {self.dtb_size}')
        lines.append(f'dtb address: {self.dtb_load_address:#018x}')
        if self.header_version > 3:
            lines.append(
                f'vendor ramdisk table size: {self.vendor_ramdisk_table_size}')
            lines.append('vendor ramdisk table: [')
            indent = lambda level: ' ' * 4 * level
            for entry in self.vendor_ramdisk_table:
                (output_ramdisk_name, ramdisk_size, ramdisk_offset,
                 ramdisk_type, ramdisk_name, board_id) = entry
                lines.append(indent(1) + f'{output_ramdisk_name}: ''{')
                lines.append(indent(2) + f'size: {ramdisk_size}')
                lines.append(indent(2) + f'offset: {ramdisk_offset}')
                lines.append(indent(2) + f'type: {ramdisk_type:#x}')
                lines.append(indent(2) + f'name: {ramdisk_name}')
                lines.append(indent(2) + 'board_id: [')
                stride = 4
                for row_idx in range(0, len(board_id), stride):
                    row = board_id[row_idx:row_idx + stride]
                    lines.append(
                        indent(3) + ' '.join(f'{e:#010x},' for e in row))
                lines.append(indent(2) + ']')
                lines.append(indent(1) + '}')
            lines.append(']')
            lines.append(
                f'vendor bootconfig size: {self.vendor_bootconfig_size}')

        return '\n'.join(lines)

    def format_mkbootimg_argument(self, null=False):
        args = []
        args.extend(['--header_version', str(self.header_version)])
        args.extend(['--pagesize', f'{self.page_size:#010x}'])
        args.extend(['--base', f'{0:#010x}'])
        args.extend(['--kernel_offset', f'{self.kernel_load_address:#010x}'])
        args.extend(['--ramdisk_offset', f'{self.ramdisk_load_address:#010x}'])
        args.extend(['--tags_offset', f'{self.tags_load_address:#010x}'])
        args.extend(['--dtb_offset', f'{self.dtb_load_address:#018x}'])
        args.extend(['--vendor_cmdline', self.cmdline])
        args.extend(['--board', self.product_name])

        dtb_path = os.path.join(self.image_dir, 'dtb')
        args.extend(['--dtb', dtb_path])

        if self.header_version > 3:
            bootconfig_path = os.path.join(self.image_dir, 'bootconfig')
            args.extend(['--vendor_bootconfig', bootconfig_path])

            for entry in self.vendor_ramdisk_table:
                (output_ramdisk_name, _, _, ramdisk_type,
                 ramdisk_name, board_id) = entry
                args.extend(['--ramdisk_type', str(ramdisk_type)])
                args.extend(['--ramdisk_name', ramdisk_name])
                for idx, e in enumerate(board_id):
                    if e:
                        args.extend([f'--board_id{idx}', f'{e:#010x}'])
                vendor_ramdisk_path = os.path.join(
                    self.image_dir, output_ramdisk_name)
                args.extend(['--vendor_ramdisk_fragment', vendor_ramdisk_path])
        else:
            vendor_ramdisk_path = os.path.join(self.image_dir, 'vendor_ramdisk')
            args.extend(['--vendor_ramdisk', vendor_ramdisk_path])

        if null:
            return '\0'.join(args) + '\0'
        return shlex.join(args)

    def format_json_dict(self):
        """Returns a dict of arguments to be used in mkbootimg.py later."""
        args_dict = {}
        args_dict['header_version'] = str(self.header_version)

        # Format uint32_t as '0xFFFFFFFF', uint64_t as '0xFFFFFFFFEEEEEEEE'.
        args_dict['pagesize'] = f'{self.page_size:#010x}'

        # Kernel load address is base + kernel_offset in mkbootimg.py.
        # However, we don't know the value of 'base' when unpacking a
        # vendor_boot.img in this script. So always set 'base' to be zero and
        # 'kernel_offset' to be the kernel load address. Same for
        # 'ramdisk_offset', 'tags_offset' and 'dtb_offset'.
        args_dict['base'] = f'{0:#010x}'
        args_dict['kernel_offset'] = f'{self.kernel_load_address:#010x}'
        args_dict['ramdisk_offset'] = f'{self.ramdisk_load_address:#010x}'
        args_dict['tags_offset'] = f'{self.tags_load_address:#010x}'
        # The type of dtb_offset is uint64_t.
        args_dict['dtb_offset'] = f'{self.dtb_load_address:#018x}'

        args_dict['vendor_cmdline'] = self.cmdline
        args_dict['board'] = self.product_name

        # TODO(bowgotsai): support for multiple vendor ramdisk (vendor boot v4).
        return args_dict


def unpack_vendor_boot_image(args):
    info = VendorBootImageInfoFormatter()
    info.boot_magic = unpack('8s', args.boot_img.read(8))[0].decode()
    info.header_version = unpack('I', args.boot_img.read(4))[0]
    info.page_size = unpack('I', args.boot_img.read(4))[0]
    info.kernel_load_address = unpack('I', args.boot_img.read(4))[0]
    info.ramdisk_load_address = unpack('I', args.boot_img.read(4))[0]
    info.vendor_ramdisk_size = unpack('I', args.boot_img.read(4))[0]
    info.cmdline = cstr(unpack('2048s', args.boot_img.read(2048))[0].decode())
    info.tags_load_address = unpack('I', args.boot_img.read(4))[0]
    info.product_name = cstr(unpack('16s', args.boot_img.read(16))[0].decode())
    info.header_size = unpack('I', args.boot_img.read(4))[0]
    info.dtb_size = unpack('I', args.boot_img.read(4))[0]
    info.dtb_load_address = unpack('Q', args.boot_img.read(8))[0]

    # Convenient shorthand.
    page_size = info.page_size
    # The first pages contain the boot header
    num_boot_header_pages = get_number_of_pages(info.header_size, page_size)
    num_boot_ramdisk_pages = get_number_of_pages(
        info.vendor_ramdisk_size, page_size)
    num_boot_dtb_pages = get_number_of_pages(info.dtb_size, page_size)

    ramdisk_offset_base = page_size * num_boot_header_pages
    image_info_list = []

    if info.header_version > 3:
        info.vendor_ramdisk_table_size = unpack('I', args.boot_img.read(4))[0]
        vendor_ramdisk_table_entry_num = unpack('I', args.boot_img.read(4))[0]
        vendor_ramdisk_table_entry_size = unpack('I', args.boot_img.read(4))[0]
        info.vendor_bootconfig_size = unpack('I', args.boot_img.read(4))[0]
        num_vendor_ramdisk_table_pages = get_number_of_pages(
            info.vendor_ramdisk_table_size, page_size)
        vendor_ramdisk_table_offset = page_size * (
            num_boot_header_pages + num_boot_ramdisk_pages + num_boot_dtb_pages)

        vendor_ramdisk_table = []
        vendor_ramdisk_symlinks = []
        for idx in range(vendor_ramdisk_table_entry_num):
            entry_offset = vendor_ramdisk_table_offset + (
                vendor_ramdisk_table_entry_size * idx)
            args.boot_img.seek(entry_offset)
            ramdisk_size = unpack('I', args.boot_img.read(4))[0]
            ramdisk_offset = unpack('I', args.boot_img.read(4))[0]
            ramdisk_type = unpack('I', args.boot_img.read(4))[0]
            ramdisk_name = cstr(unpack(
                f'{VENDOR_RAMDISK_NAME_SIZE}s',
                args.boot_img.read(VENDOR_RAMDISK_NAME_SIZE))[0].decode())
            board_id = unpack(
                f'{VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE}I',
                args.boot_img.read(
                    4 * VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE))
            output_ramdisk_name = f'vendor_ramdisk{idx:02}'

            image_info_list.append((ramdisk_offset_base + ramdisk_offset,
                                    ramdisk_size, output_ramdisk_name))
            vendor_ramdisk_symlinks.append((output_ramdisk_name, ramdisk_name))
            vendor_ramdisk_table.append(
                (output_ramdisk_name, ramdisk_size, ramdisk_offset,
                 ramdisk_type, ramdisk_name, board_id))

        info.vendor_ramdisk_table = vendor_ramdisk_table

        bootconfig_offset = page_size * (num_boot_header_pages
            + num_boot_ramdisk_pages + num_boot_dtb_pages
            + num_vendor_ramdisk_table_pages)
        image_info_list.append((bootconfig_offset, info.vendor_bootconfig_size,
            'bootconfig'))
    else:
        image_info_list.append(
            (ramdisk_offset_base, info.vendor_ramdisk_size, 'vendor_ramdisk'))

    dtb_offset = page_size * (num_boot_header_pages + num_boot_ramdisk_pages
                             ) # header + vendor_ramdisk
    image_info_list.append((dtb_offset, info.dtb_size, 'dtb'))

    for image_info in image_info_list:
        extract_image(image_info[0], image_info[1], args.boot_img,
                      os.path.join(args.out, image_info[2]))

    if info.header_version > 3:
        vendor_ramdisk_by_name_dir = os.path.join(
            args.out, 'vendor-ramdisk-by-name')
        create_out_dir(vendor_ramdisk_by_name_dir)
        for src, dst in vendor_ramdisk_symlinks:
            src_pathname = os.path.join('..', src)
            dst_pathname = os.path.join(
                vendor_ramdisk_by_name_dir, f'ramdisk_{dst}')
            if os.path.lexists(dst_pathname):
                os.remove(dst_pathname)
            os.symlink(src_pathname, dst_pathname)

    info.image_dir = args.out

    # Saves the arguments to be reused in mkbootimg.py later.
    mkbootimg_args = info.format_json_dict()
    with open(os.path.join(args.out, MKBOOTIMG_ARGS_FILE), 'w') as f:
        json.dump(mkbootimg_args, f, sort_keys=True, indent=4)

    if args.format == 'mkbootimg':
        print(info.format_mkbootimg_argument(null=args.null),
              end='' if args.null else None)
    else:
        print(info.format_pretty_text())


def unpack_image(args):
    boot_magic = unpack('8s', args.boot_img.read(8))[0].decode()
    args.boot_img.seek(0)
    if boot_magic == 'ANDROID!':
        unpack_boot_image(args)
    elif boot_magic == 'VNDRBOOT':
        unpack_vendor_boot_image(args)


def get_unpack_usage():
    return """Output format:

  * info

    Pretty-printed info-rich text format suitable for human inspection.

  * mkbootimg

    Output shell-escaped (quoted) argument strings that can be used to
    reconstruct the boot image. For example:

    $ unpack_bootimg --boot_img vendor_boot.img --out out --format=mkbootimg |
        tee mkbootimg_args
    $ sh -c "mkbootimg $(cat mkbootimg_args) --vendor_boot repacked.img"

    vendor_boot.img and repacked.img would be equivalent.

    If the -0 option is specified, output unescaped null-terminated argument
    strings that are suitable to be parsed by a shell script (xargs -0 format):

    $ unpack_bootimg --boot_img vendor_boot.img --out out --format=mkbootimg \\
        -0 | tee mkbootimg_args
    $ declare -a MKBOOTIMG_ARGS=()
    $ while IFS= read -r -d '' ARG; do
        MKBOOTIMG_ARGS+=("${ARG}")
      done <mkbootimg_args
    $ mkbootimg "${MKBOOTIMG_ARGS[@]}" --vendor_boot repacked.img
"""


def parse_cmdline():
    """parse command line arguments"""
    parser = ArgumentParser(
        formatter_class=RawDescriptionHelpFormatter,
        description='Unpacks boot, recovery or vendor_boot image.',
        epilog=get_unpack_usage(),
    )
    parser.add_argument('--boot_img', type=FileType('rb'), required=True,
                        help='path to the boot, recovery or vendor_boot image')
    parser.add_argument('--out', default='out',
                        help='output directory of the unpacked images')
    parser.add_argument('--format', choices=['info', 'mkbootimg'],
                        default='info',
                        help='text output format (default: info)')
    parser.add_argument('-0', '--null', action='store_true',
                        help='output null-terminated argument strings')
    return parser.parse_args()


def main():
    """parse arguments and unpack boot image"""
    args = parse_cmdline()
    create_out_dir(args.out)
    unpack_image(args)


if __name__ == '__main__':
    main()
