#!/usr/bin/python
from __future__ import print_function

import cmd
import optparse
import os
import shlex
import struct
import sys

ARMAG = "!<arch>\n"
SARMAG = 8
ARFMAG = "`\n"
AR_EFMT1 = "#1/"


def memdump(src, bytes_per_line=16, address=0):
    FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.'
                     for x in range(256)])
    for i in range(0, len(src), bytes_per_line):
        s = src[i:i+bytes_per_line]
        hex_bytes = ' '.join(["%02x" % (ord(x)) for x in s])
        ascii = s.translate(FILTER)
        print("%#08.8x: %-*s %s" % (address+i, bytes_per_line*3, hex_bytes,
                                    ascii))


class Object(object):
    def __init__(self, file):
        def read_str(file, str_len):
            return file.read(str_len).rstrip('\0 ')

        def read_int(file, str_len, base):
            return int(read_str(file, str_len), base)

        self.offset = file.tell()
        self.file = file
        self.name = read_str(file, 16)
        self.date = read_int(file, 12, 10)
        self.uid = read_int(file, 6, 10)
        self.gid = read_int(file, 6, 10)
        self.mode = read_int(file, 8, 8)
        self.size = read_int(file, 10, 10)
        if file.read(2) != ARFMAG:
            raise ValueError('invalid BSD object at offset %#08.8x' % (
                             self.offset))
        # If we have an extended name read it. Extended names start with
        name_len = 0
        if self.name.startswith(AR_EFMT1):
            name_len = int(self.name[len(AR_EFMT1):], 10)
            self.name = read_str(file, name_len)
        self.obj_offset = file.tell()
        self.obj_size = self.size - name_len
        file.seek(self.obj_size, 1)

    def dump(self, f=sys.stdout, flat=True):
        if flat:
            f.write('%#08.8x: %#08.8x %5u %5u %6o %#08.8x %s\n' % (self.offset,
                    self.date, self.uid, self.gid, self.mode, self.size,
                    self.name))
        else:
            f.write('%#08.8x: \n' % self.offset)
            f.write(' name = "%s"\n' % self.name)
            f.write(' date = %#08.8x\n' % self.date)
            f.write('  uid = %i\n' % self.uid)
            f.write('  gid = %i\n' % self.gid)
            f.write(' mode = %o\n' % self.mode)
            f.write(' size = %#08.8x\n' % (self.size))
            self.file.seek(self.obj_offset, 0)
            first_bytes = self.file.read(4)
            f.write('bytes = ')
            memdump(first_bytes)

    def get_bytes(self):
        saved_pos = self.file.tell()
        self.file.seek(self.obj_offset, 0)
        bytes = self.file.read(self.obj_size)
        self.file.seek(saved_pos, 0)
        return bytes

    def save(self, path=None, overwrite=False):
        '''
            Save the contents of the object to disk using 'path' argument as
            the path, or save it to the current working directory using the
            object name.
        '''

        if path is None:
            path = self.name
        if not overwrite and os.path.exists(path):
            print('error: outfile "%s" already exists' % (path))
            return
        print('Saving "%s" to "%s"...' % (self.name, path))
        with open(path, 'w') as f:
            f.write(self.get_bytes())


class StringTable(object):
    def __init__(self, bytes):
        self.bytes = bytes

    def get_string(self, offset):
        length = len(self.bytes)
        if offset >= length:
            return None
        return self.bytes[offset:self.bytes.find('\0', offset)]


class Archive(object):
    def __init__(self, path):
        self.path = path
        self.file = open(path, 'r')
        self.objects = []
        self.offset_to_object = {}
        if self.file.read(SARMAG) != ARMAG:
            print("error: file isn't a BSD archive")
        while True:
            try:
                self.objects.append(Object(self.file))
            except ValueError:
                break

    def get_object_at_offset(self, offset):
        if offset in self.offset_to_object:
            return self.offset_to_object[offset]
        for obj in self.objects:
            if obj.offset == offset:
                self.offset_to_object[offset] = obj
                return obj
        return None

    def find(self, name, mtime=None, f=sys.stdout):
        '''
            Find an object(s) by name with optional modification time. There
            can be multple objects with the same name inside and possibly with
            the same modification time within a BSD archive so clients must be
            prepared to get multiple results.
        '''
        matches = []
        for obj in self.objects:
            if obj.name == name and (mtime is None or mtime == obj.date):
                matches.append(obj)
        return matches

    @classmethod
    def dump_header(self, f=sys.stdout):
        f.write('            DATE       UID   GID   MODE   SIZE       NAME\n')
        f.write('            ---------- ----- ----- ------ ---------- '
                '--------------\n')

    def get_symdef(self):
        def get_uint32(file):
            '''Extract a uint32_t from the current file position.'''
            v, = struct.unpack('=I', file.read(4))
            return v

        for obj in self.objects:
            symdef = []
            if obj.name.startswith("__.SYMDEF"):
                self.file.seek(obj.obj_offset, 0)
                ranlib_byte_size = get_uint32(self.file)
                num_ranlib_structs = ranlib_byte_size/8
                str_offset_pairs = []
                for _ in range(num_ranlib_structs):
                    strx = get_uint32(self.file)
                    offset = get_uint32(self.file)
                    str_offset_pairs.append((strx, offset))
                strtab_len = get_uint32(self.file)
                strtab = StringTable(self.file.read(strtab_len))
                for s in str_offset_pairs:
                    symdef.append((strtab.get_string(s[0]), s[1]))
            return symdef

    def get_object_dicts(self):
        '''
            Returns an array of object dictionaries that contain they following
            keys:
                'object': the actual bsd.Object instance
                'symdefs': an array of symbol names that the object contains
                           as found in the "__.SYMDEF" item in the archive
        '''
        symdefs = self.get_symdef()
        symdef_dict = {}
        if symdefs:
            for (name, offset) in symdefs:
                if offset in symdef_dict:
                    object_dict = symdef_dict[offset]
                else:
                    object_dict = {
                        'object': self.get_object_at_offset(offset),
                        'symdefs': []
                    }
                    symdef_dict[offset] = object_dict
                object_dict['symdefs'].append(name)
        object_dicts = []
        for offset in sorted(symdef_dict):
            object_dicts.append(symdef_dict[offset])
        return object_dicts

    def dump(self, f=sys.stdout, flat=True):
        f.write('%s:\n' % self.path)
        if flat:
            self.dump_header(f=f)
        for obj in self.objects:
            obj.dump(f=f, flat=flat)

class Interactive(cmd.Cmd):
    '''Interactive prompt for exploring contents of BSD archive files, type
      "help" to see a list of supported commands.'''
    image_option_parser = None

    def __init__(self, archives):
        cmd.Cmd.__init__(self)
        self.use_rawinput = False
        self.intro = ('Interactive  BSD archive prompt, type "help" to see a '
                      'list of supported commands.')
        self.archives = archives
        self.prompt = '% '

    def default(self, line):
        '''Catch all for unknown command, which will exit the interpreter.'''
        print("unknown command: %s" % line)
        return True

    def do_q(self, line):
        '''Quit command'''
        return True

    def do_quit(self, line):
        '''Quit command'''
        return True

    def do_extract(self, line):
        args = shlex.split(line)
        if args:
            extracted = False
            for object_name in args:
                for archive in self.archives:
                    matches = archive.find(object_name)
                    if matches:
                        for object in matches:
                            object.save(overwrite=False)
                            extracted = True
            if not extracted:
                print('error: no object matches "%s" in any archives' % (
                        object_name))
        else:
            print('error: must specify the name of an object to extract')

    def do_ls(self, line):
        args = shlex.split(line)
        if args:
            for object_name in args:
                for archive in self.archives:
                    matches = archive.find(object_name)
                    if matches:
                        for object in matches:
                            object.dump(flat=False)
                    else:
                        print('error: no object matches "%s" in "%s"' % (
                                object_name, archive.path))
        else:
            for archive in self.archives:
                archive.dump(flat=True)
                print('')



def main():
    parser = optparse.OptionParser(
        prog='bsd',
        description='Utility for BSD archives')
    parser.add_option(
        '--object',
        type='string',
        dest='object_name',
        default=None,
        help=('Specify the name of a object within the BSD archive to get '
              'information on'))
    parser.add_option(
        '-s', '--symbol',
        type='string',
        dest='find_symbol',
        default=None,
        help=('Specify the name of a symbol within the BSD archive to get '
              'information on from SYMDEF'))
    parser.add_option(
        '--symdef',
        action='store_true',
        dest='symdef',
        default=False,
        help=('Dump the information in the SYMDEF.'))
    parser.add_option(
        '-v', '--verbose',
        action='store_true',
        dest='verbose',
        default=False,
        help='Enable verbose output')
    parser.add_option(
        '-e', '--extract',
        action='store_true',
        dest='extract',
        default=False,
        help=('Specify this to extract the object specified with the --object '
              'option. There must be only one object with a matching name or '
              'the --mtime option must be specified to uniquely identify a '
              'single object.'))
    parser.add_option(
        '-m', '--mtime',
        type='int',
        dest='mtime',
        default=None,
        help=('Specify the modification time of the object an object. This '
              'option is used with either the --object or --extract options.'))
    parser.add_option(
        '-o', '--outfile',
        type='string',
        dest='outfile',
        default=None,
        help=('Specify a different name or path for the file to extract when '
              'using the --extract option. If this option isn\'t specified, '
              'then the extracted object file will be extracted into the '
              'current working directory if a file doesn\'t already exist '
              'with that name.'))
    parser.add_option(
        '-i', '--interactive',
        action='store_true',
        dest='interactive',
        default=False,
        help=('Enter an interactive shell that allows users to interactively '
              'explore contents of .a files.'))

    (options, args) = parser.parse_args(sys.argv[1:])

    if options.interactive:
        archives = []
        for path in args:
            archives.append(Archive(path))
        interpreter = Interactive(archives)
        interpreter.cmdloop()
        return

    for path in args:
        archive = Archive(path)
        if options.object_name:
            print('%s:\n' % (path))
            matches = archive.find(options.object_name, options.mtime)
            if matches:
                dump_all = True
                if options.extract:
                    if len(matches) == 1:
                        dump_all = False
                        matches[0].save(path=options.outfile, overwrite=False)
                    else:
                        print('error: multiple objects match "%s". Specify '
                              'the modification time using --mtime.' % (
                                options.object_name))
                if dump_all:
                    for obj in matches:
                        obj.dump(flat=False)
            else:
                print('error: object "%s" not found in archive' % (
                      options.object_name))
        elif options.find_symbol:
            symdefs = archive.get_symdef()
            if symdefs:
                success = False
                for (name, offset) in symdefs:
                    obj = archive.get_object_at_offset(offset)
                    if name == options.find_symbol:
                        print('Found "%s" in:' % (options.find_symbol))
                        obj.dump(flat=False)
                        success = True
                if not success:
                    print('Didn\'t find "%s" in any objects' % (
                          options.find_symbol))
            else:
                print("error: no __.SYMDEF was found")
        elif options.symdef:
            object_dicts = archive.get_object_dicts()
            for object_dict in object_dicts:
                object_dict['object'].dump(flat=False)
                print("symbols:")
                for name in object_dict['symdefs']:
                    print("  %s" % (name))
        else:
            archive.dump(flat=not options.verbose)


if __name__ == '__main__':
    main()


def print_mtime_error(result, dmap_mtime, actual_mtime):
    print("error: modification time in debug map (%#08.8x) doesn't "
                     "match the .o file modification time (%#08.8x)" % (
                        dmap_mtime, actual_mtime), file=result)


def print_file_missing_error(result, path):
    print("error: file \"%s\" doesn't exist" % (path), file=result)


def print_multiple_object_matches(result, object_name, mtime, matches):
    print("error: multiple matches for object '%s' with with "
                     "modification time %#08.8x:" % (object_name, mtime), file=result)
    Archive.dump_header(f=result)
    for match in matches:
        match.dump(f=result, flat=True)


def print_archive_object_error(result, object_name, mtime, archive):
    matches = archive.find(object_name, f=result)
    if len(matches) > 0:
        print("error: no objects have a modification time that "
                         "matches %#08.8x for '%s'. Potential matches:" % (
                            mtime, object_name), file=result)
        Archive.dump_header(f=result)
        for match in matches:
            match.dump(f=result, flat=True)
    else:
        print("error: no object named \"%s\" found in archive:" % (
            object_name), file=result)
        Archive.dump_header(f=result)
        for match in archive.objects:
            match.dump(f=result, flat=True)
        # archive.dump(f=result, flat=True)


class VerifyDebugMapCommand:
    name = "verify-debug-map-objects"

    def create_options(self):
        usage = "usage: %prog [options]"
        description = '''This command reports any .o files that are missing
or whose modification times don't match in the debug map of an executable.'''

        self.parser = optparse.OptionParser(
            description=description,
            prog=self.name,
            usage=usage,
            add_help_option=False)

        self.parser.add_option(
            '-e', '--errors',
            action='store_true',
            dest='errors',
            default=False,
            help="Only show errors")

    def get_short_help(self):
        return "Verify debug map object files."

    def get_long_help(self):
        return self.help_string

    def __init__(self, debugger, unused):
        self.create_options()
        self.help_string = self.parser.format_help()

    def __call__(self, debugger, command, exe_ctx, result):
        import lldb
        # Use the Shell Lexer to properly parse up command options just like a
        # shell would
        command_args = shlex.split(command)

        try:
            (options, args) = self.parser.parse_args(command_args)
        except:
            result.SetError("option parsing failed")
            return

        # Always get program state from the SBExecutionContext passed in
        target = exe_ctx.GetTarget()
        if not target.IsValid():
            result.SetError("invalid target")
            return
        archives = {}
        for module_spec in args:
            module = target.module[module_spec]
            if not (module and module.IsValid()):
                result.SetError('error: invalid module specification: "%s". '
                                'Specify the full path, basename, or UUID of '
                                'a module ' % (module_spec))
                return
            num_symbols = module.GetNumSymbols()
            num_errors = 0
            for i in range(num_symbols):
                symbol = module.GetSymbolAtIndex(i)
                if symbol.GetType() != lldb.eSymbolTypeObjectFile:
                    continue
                path = symbol.GetName()
                if not path:
                    continue
                # Extract the value of the symbol by dumping the
                # symbol. The value is the mod time.
                dmap_mtime = int(str(symbol).split('value = ')
                                 [1].split(',')[0], 16)
                if not options.errors:
                    print('%s' % (path), file=result)
                if os.path.exists(path):
                    actual_mtime = int(os.stat(path).st_mtime)
                    if dmap_mtime != actual_mtime:
                        num_errors += 1
                        if options.errors:
                            print('%s' % (path), end=' ', file=result)
                        print_mtime_error(result, dmap_mtime,
                                          actual_mtime)
                elif path[-1] == ')':
                    (archive_path, object_name) = path[0:-1].split('(')
                    if not archive_path and not object_name:
                        num_errors += 1
                        if options.errors:
                            print('%s' % (path), end=' ', file=result)
                        print_file_missing_error(path)
                        continue
                    if not os.path.exists(archive_path):
                        num_errors += 1
                        if options.errors:
                            print('%s' % (path), end=' ', file=result)
                        print_file_missing_error(archive_path)
                        continue
                    if archive_path in archives:
                        archive = archives[archive_path]
                    else:
                        archive = Archive(archive_path)
                        archives[archive_path] = archive
                    matches = archive.find(object_name, dmap_mtime)
                    num_matches = len(matches)
                    if num_matches == 1:
                        print('1 match', file=result)
                        obj = matches[0]
                        if obj.date != dmap_mtime:
                            num_errors += 1
                            if options.errors:
                                print('%s' % (path), end=' ', file=result)
                            print_mtime_error(result, dmap_mtime, obj.date)
                    elif num_matches == 0:
                        num_errors += 1
                        if options.errors:
                            print('%s' % (path), end=' ', file=result)
                        print_archive_object_error(result, object_name,
                                                   dmap_mtime, archive)
                    elif num_matches > 1:
                        num_errors += 1
                        if options.errors:
                            print('%s' % (path), end=' ', file=result)
                        print_multiple_object_matches(result,
                                                      object_name,
                                                      dmap_mtime, matches)
            if num_errors > 0:
                print("%u errors found" % (num_errors), file=result)
            else:
                print("No errors detected in debug map", file=result)


def __lldb_init_module(debugger, dict):
    # This initializer is being run from LLDB in the embedded command
    # interpreter.
    # Add any commands contained in this module to LLDB
    debugger.HandleCommand(
        'command script add -c %s.VerifyDebugMapCommand %s' % (
            __name__, VerifyDebugMapCommand.name))
    print('The "%s" command has been installed, type "help %s" for detailed '
          'help.' % (VerifyDebugMapCommand.name, VerifyDebugMapCommand.name))
