#!/usr/bin/python

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 >>result, ("error: modification time in debug map (%#08.8x) doesn't "
                     "match the .o file modification time (%#08.8x)" % (
                        dmap_mtime, actual_mtime))


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


def print_multiple_object_matches(result, object_name, mtime, matches):
    print >>result, ("error: multiple matches for object '%s' with with "
                     "modification time %#08.8x:" % (object_name, mtime))
    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 >>result, ("error: no objects have a modification time that "
                         "matches %#08.8x for '%s'. Potential matches:" % (
                            mtime, object_name))
        Archive.dump_header(f=result)
        for match in matches:
            match.dump(f=result, flat=True)
    else:
        print >>result, "error: no object named \"%s\" found in archive:" % (
            object_name)
        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 >>result, '%s' % (path)
                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 >>result, '%s' % (path),
                        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 >>result, '%s' % (path),
                        print_file_missing_error(path)
                        continue
                    if not os.path.exists(archive_path):
                        num_errors += 1
                        if options.errors:
                            print >>result, '%s' % (path),
                        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 >>result, '1 match'
                        obj = matches[0]
                        if obj.date != dmap_mtime:
                            num_errors += 1
                            if options.errors:
                                print >>result, '%s' % (path),
                            print_mtime_error(result, dmap_mtime, obj.date)
                    elif num_matches == 0:
                        num_errors += 1
                        if options.errors:
                            print >>result, '%s' % (path),
                        print_archive_object_error(result, object_name,
                                                   dmap_mtime, archive)
                    elif num_matches > 1:
                        num_errors += 1
                        if options.errors:
                            print >>result, '%s' % (path),
                        print_multiple_object_matches(result,
                                                      object_name,
                                                      dmap_mtime, matches)
            if num_errors > 0:
                print >>result, "%u errors found" % (num_errors)
            else:
                print >>result, "No errors detected in debug map"


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