#!/usr/bin/env python

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

# Usage: strip_save_dsym <whatever-arguments-you-would-pass-to-strip>
#
# strip_save_dsym is a wrapper around the standard strip utility.  Given an
# input Mach-O file, strip_save_dsym will save a copy of the file in a "fake"
# .dSYM bundle for debugging, and then call strip to strip the Mach-O file.
# Note that the .dSYM file is a "fake" in that it's not a self-contained
# .dSYM bundle, it just contains a copy of the original (unstripped) Mach-O
# file, and therefore contains references to object files on the filesystem.
# The generated .dSYM bundle is therefore unsuitable for debugging in the
# absence of these .o files.
#
# If a .dSYM already exists and has a newer timestamp than the Mach-O file,
# this utility does nothing.  That allows strip_save_dsym to be run on a file
# that has already been stripped without trashing the .dSYM.
#
# Rationale: the "right" way to generate dSYM bundles, dsymutil, is incredibly
# slow.  On the other hand, doing a file copy (which is really all that
# dsymutil does) is comparatively fast.  Since we usually just want to strip
# a release-mode executable but still be able to debug it, and we don't care
# so much about generating a hermetic dSYM bundle, we'll prefer the file copy.
# If a real dSYM is ever needed, it's still possible to create one by running
# dsymutil and pointing it at the original Mach-O file inside the "fake"
# bundle, provided that the object files are available.

import errno
import os
import re
import shutil
import subprocess
import sys
import time

# Returns a list of architectures contained in a Mach-O file.  The file can be
# a universal (fat) file, in which case there will be one list element for
# each contained architecture, or it can be a thin single-architecture Mach-O
# file, in which case the list will contain a single element identifying the
# architecture.  On error, returns an empty list.  Determines the architecture
# list by calling file.
def macho_archs(macho):
  macho_types = ["executable",
                 "dynamically linked shared library",
                 "bundle"]
  macho_types_re = "Mach-O (?:64-bit )?(?:" + "|".join(macho_types) + ")"

  file_cmd = subprocess.Popen(["/usr/bin/file", "-b", "--", macho],
                              stdout=subprocess.PIPE)

  archs = []

  type_line = file_cmd.stdout.readline()
  type_match = re.match("^%s (.*)$" % macho_types_re, type_line)
  if type_match:
    archs.append(type_match.group(1))
    return [type_match.group(1)]
  else:
    type_match = re.match("^Mach-O universal binary with (.*) architectures$",
                          type_line)
    if type_match:
      for i in range(0, int(type_match.group(1))):
        arch_line = file_cmd.stdout.readline()
        arch_match = re.match(
                     "^.* \(for architecture (.*)\):\t%s .*$" % macho_types_re,
                     arch_line)
        if arch_match:
          archs.append(arch_match.group(1))

  if file_cmd.wait() != 0:
    archs = []

  if len(archs) == 0:
    print >> sys.stderr, "No architectures in %s" % macho

  return archs

# Returns a dictionary mapping architectures contained in the file as returned
# by macho_archs to the LC_UUID load command for that architecture.
# Architectures with no LC_UUID load command are omitted from the dictionary.
# Determines the UUID value by calling otool.
def macho_uuids(macho):
  uuids = {}

  archs = macho_archs(macho)
  if len(archs) == 0:
    return uuids

  for arch in archs:
    if arch == "":
      continue

    otool_cmd = subprocess.Popen(["/usr/bin/otool", "-arch", arch, "-l", "-",
                                  macho],
                                 stdout=subprocess.PIPE)
    # state 0 is when nothing UUID-related has been seen yet.  State 1 is
    # entered after a load command begins, but it may not be an LC_UUID load
    # command.  States 2, 3, and 4 are intermediate states while reading an
    # LC_UUID command.  State 5 is the terminal state for a successful LC_UUID
    # read.  State 6 is the error state.
    state = 0
    uuid = ""
    for otool_line in otool_cmd.stdout:
      if state == 0:
        if re.match("^Load command .*$", otool_line):
          state = 1
      elif state == 1:
        if re.match("^     cmd LC_UUID$", otool_line):
          state = 2
        else:
          state = 0
      elif state == 2:
        if re.match("^ cmdsize 24$", otool_line):
          state = 3
        else:
          state = 6
      elif state == 3:
        # The UUID display format changed in the version of otool shipping
        # with the Xcode 3.2.2 prerelease.  The new format is traditional:
        #    uuid 4D7135B2-9C56-C5F5-5F49-A994258E0955
        # and with Xcode 3.2.6, then line is indented one more space:
        #     uuid 4D7135B2-9C56-C5F5-5F49-A994258E0955
        # The old format, from cctools-750 and older's otool, breaks the UUID
        # up into a sequence of bytes:
        #    uuid 0x4d 0x71 0x35 0xb2 0x9c 0x56 0xc5 0xf5
        #         0x5f 0x49 0xa9 0x94 0x25 0x8e 0x09 0x55
        new_uuid_match = re.match("^ {3,4}uuid (.{8}-.{4}-.{4}-.{4}-.{12})$",
                                  otool_line)
        if new_uuid_match:
          uuid = new_uuid_match.group(1)

          # Skip state 4, there is no second line to read.
          state = 5
        else:
          old_uuid_match = re.match("^   uuid 0x(..) 0x(..) 0x(..) 0x(..) "
                                    "0x(..) 0x(..) 0x(..) 0x(..)$",
                                    otool_line)
          if old_uuid_match:
            state = 4
            uuid = old_uuid_match.group(1) + old_uuid_match.group(2) + \
                   old_uuid_match.group(3) + old_uuid_match.group(4) + "-" + \
                   old_uuid_match.group(5) + old_uuid_match.group(6) + "-" + \
                   old_uuid_match.group(7) + old_uuid_match.group(8) + "-"
          else:
            state = 6
      elif state == 4:
        old_uuid_match = re.match("^        0x(..) 0x(..) 0x(..) 0x(..) "
                                  "0x(..) 0x(..) 0x(..) 0x(..)$",
                                  otool_line)
        if old_uuid_match:
          state = 5
          uuid += old_uuid_match.group(1) + old_uuid_match.group(2) + "-" + \
                  old_uuid_match.group(3) + old_uuid_match.group(4) + \
                  old_uuid_match.group(5) + old_uuid_match.group(6) + \
                  old_uuid_match.group(7) + old_uuid_match.group(8)
        else:
          state = 6

    if otool_cmd.wait() != 0:
      state = 6

    if state == 5:
      uuids[arch] = uuid.upper()

  if len(uuids) == 0:
    print >> sys.stderr, "No UUIDs in %s" % macho

  return uuids

# Given a path to a Mach-O file and possible information from the environment,
# determines the desired path to the .dSYM.
def dsym_path(macho):
  # If building a bundle, the .dSYM should be placed next to the bundle.  Use
  # WRAPPER_NAME to make this determination.  If called from xcodebuild,
  # WRAPPER_NAME will be set to the name of the bundle.
  dsym = ""
  if "WRAPPER_NAME" in os.environ:
    if "BUILT_PRODUCTS_DIR" in os.environ:
      dsym = os.path.join(os.environ["BUILT_PRODUCTS_DIR"],
                          os.environ["WRAPPER_NAME"])
    else:
      dsym = os.environ["WRAPPER_NAME"]
  else:
    dsym = macho

  dsym += ".dSYM"

  return dsym

# Creates a fake .dSYM bundle at dsym for macho, a Mach-O image with the
# architectures and UUIDs specified by the uuids map.
def make_fake_dsym(macho, dsym):
  uuids = macho_uuids(macho)
  if len(uuids) == 0:
    return False

  dwarf_dir = os.path.join(dsym, "Contents", "Resources", "DWARF")
  dwarf_file = os.path.join(dwarf_dir, os.path.basename(macho))
  try:
    os.makedirs(dwarf_dir)
  except OSError, (err, error_string):
    if err != errno.EEXIST:
      raise
  shutil.copyfile(macho, dwarf_file)

  # info_template is the same as what dsymutil would have written, with the
  # addition of the fake_dsym key.
  info_template = \
'''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<key>CFBundleDevelopmentRegion</key>
		<string>English</string>
		<key>CFBundleIdentifier</key>
		<string>com.apple.xcode.dsym.%(root_name)s</string>
		<key>CFBundleInfoDictionaryVersion</key>
		<string>6.0</string>
		<key>CFBundlePackageType</key>
		<string>dSYM</string>
		<key>CFBundleSignature</key>
		<string>????</string>
		<key>CFBundleShortVersionString</key>
		<string>1.0</string>
		<key>CFBundleVersion</key>
		<string>1</string>
		<key>dSYM_UUID</key>
		<dict>
%(uuid_dict)s		</dict>
		<key>fake_dsym</key>
		<true/>
	</dict>
</plist>
'''

  root_name = os.path.basename(dsym)[:-5]  # whatever.dSYM without .dSYM
  uuid_dict = ""
  for arch in sorted(uuids):
    uuid_dict += "\t\t\t<key>" + arch + "</key>\n"\
                 "\t\t\t<string>" + uuids[arch] + "</string>\n"
  info_dict = {
    "root_name": root_name,
    "uuid_dict": uuid_dict,
  }
  info_contents = info_template % info_dict
  info_file = os.path.join(dsym, "Contents", "Info.plist")
  info_fd = open(info_file, "w")
  info_fd.write(info_contents)
  info_fd.close()

  return True

# For a Mach-O file, determines where the .dSYM bundle should be located.  If
# the bundle does not exist or has a modification time older than the Mach-O
# file, calls make_fake_dsym to create a fake .dSYM bundle there, then strips
# the Mach-O file and sets the modification time on the .dSYM bundle and Mach-O
# file to be identical.
def strip_and_make_fake_dsym(macho):
  dsym = dsym_path(macho)
  macho_stat = os.stat(macho)
  dsym_stat = None
  try:
    dsym_stat = os.stat(dsym)
  except OSError, (err, error_string):
    if err != errno.ENOENT:
      raise

  if dsym_stat is None or dsym_stat.st_mtime < macho_stat.st_mtime:
    # Make a .dSYM bundle
    if not make_fake_dsym(macho, dsym):
      return False

    # Strip the Mach-O file
    remove_dsym = True
    try:
      strip_cmdline = ['xcrun', 'strip'] + sys.argv[1:]
      strip_cmd = subprocess.Popen(strip_cmdline)
      if strip_cmd.wait() == 0:
        remove_dsym = False
    finally:
      if remove_dsym:
        shutil.rmtree(dsym)

    # Update modification time on the Mach-O file and .dSYM bundle
    now = time.time()
    os.utime(macho, (now, now))
    os.utime(dsym, (now, now))

  return True

def main(argv=None):
  if argv is None:
    argv = sys.argv

  # This only supports operating on one file at a time.  Look at the arguments
  # to strip to figure out what the source to be stripped is.  Arguments are
  # processed in the same way that strip does, although to reduce complexity,
  # this doesn't do all of the same checking as strip.  For example, strip
  # has no -Z switch and would treat -Z on the command line as an error.  For
  # the purposes this is needed for, that's fine.
  macho = None
  process_switches = True
  ignore_argument = False
  for arg in argv[1:]:
    if ignore_argument:
      ignore_argument = False
      continue
    if process_switches:
      if arg == "-":
        process_switches = False
      # strip has these switches accept an argument:
      if arg in ["-s", "-R", "-d", "-o", "-arch"]:
        ignore_argument = True
      if arg[0] == "-":
        continue
    if macho is None:
      macho = arg
    else:
      print >> sys.stderr, "Too many things to strip"
      return 1

  if macho is None:
    print >> sys.stderr, "Nothing to strip"
    return 1

  if not strip_and_make_fake_dsym(macho):
    return 1

  return 0

if __name__ == "__main__":
  sys.exit(main(sys.argv))
