#!/usr/bin/env python3
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Wraps ml.exe or ml64.exe and postprocesses the output to be deterministic.
Sets timestamp in .obj file to 0, hence incompatible with link.exe /incremental.

Use by prefixing the ml(64).exe invocation with this script:
    python ml.py ml.exe [args...]"""

import array
import collections
import struct
import subprocess
import sys


class Struct(object):
  """A thin wrapper around the struct module that returns a namedtuple"""

  def __init__(self, name, *args):
    """Pass the name of the return type, and then an interleaved list of
    format strings as used by the struct module and of field names."""
    self.fmt = '<' + ''.join(args[0::2])
    self.type = collections.namedtuple(name, args[1::2])

  def pack_into(self, buffer, offset, data):
    return struct.pack_into(self.fmt, buffer, offset, *data)

  def unpack_from(self, buffer, offset=0):
    return self.type(*struct.unpack_from(self.fmt, buffer, offset))

  def size(self):
    return struct.calcsize(self.fmt)


def Subtract(nt, **kwargs):
  """Subtract(nt, f=2) returns a new namedtuple with 2 subtracted from nt.f"""
  return nt._replace(**{k: getattr(nt, k) - v for k, v in kwargs.items()})


def MakeDeterministic(objdata):
  # Takes data produced by ml(64).exe (without any special flags) and
  # 1. Sets the timestamp to 0
  # 2. Strips the .debug$S section (which contains an unwanted absolute path)

  # This makes several assumptions about ml's output:
  # - Section data is in the same order as the corresponding section headers:
  #   section headers preceding the .debug$S section header have their data
  #   preceding the .debug$S section data; likewise for section headers
  #   following the .debug$S section.
  # - The .debug$S section contains only the absolute path to the obj file and
  #   nothing else, in particular there's only a single entry in the symbol
  #   table referring to the .debug$S section.
  # - There are no COFF line number entries.
  # - There's no IMAGE_SYM_CLASS_CLR_TOKEN symbol.
  # These seem to hold in practice; if they stop holding this script needs to
  # become smarter.

  objdata = array.array('b', objdata)  # Writable, e.g. via struct.pack_into.

  # Read coff header.
  COFFHEADER = Struct('COFFHEADER', 'H', 'Machine', 'H', 'NumberOfSections',
                      'I', 'TimeDateStamp', 'I', 'PointerToSymbolTable', 'I',
                      'NumberOfSymbols', 'H', 'SizeOfOptionalHeader', 'H',
                      'Characteristics')
  coff_header = COFFHEADER.unpack_from(objdata)
  assert coff_header.SizeOfOptionalHeader == 0  # Only set for binaries.

  # Read section headers following coff header.
  SECTIONHEADER = Struct('SECTIONHEADER', '8s', 'Name', 'I', 'VirtualSize', 'I',
                         'VirtualAddress', 'I', 'SizeOfRawData', 'I',
                         'PointerToRawData', 'I', 'PointerToRelocations', 'I',
                         'PointerToLineNumbers', 'H', 'NumberOfRelocations',
                         'H', 'NumberOfLineNumbers', 'I', 'Characteristics')
  section_headers = []
  debug_section_index = -1
  for i in range(0, coff_header.NumberOfSections):
    section_header = SECTIONHEADER.unpack_from(objdata,
                                               offset=COFFHEADER.size() +
                                               i * SECTIONHEADER.size())
    assert not section_header[0].startswith(b'/')  # Support short names only.
    section_headers.append(section_header)

    if section_header.Name == b'.debug$S':
      assert debug_section_index == -1
      debug_section_index = i
  assert debug_section_index != -1

  data_start = COFFHEADER.size() + len(section_headers) * SECTIONHEADER.size()

  # Verify the .debug$S section looks like we expect.
  assert section_headers[debug_section_index].Name == b'.debug$S'
  assert section_headers[debug_section_index].VirtualSize == 0
  assert section_headers[debug_section_index].VirtualAddress == 0
  debug_size = section_headers[debug_section_index].SizeOfRawData
  debug_offset = section_headers[debug_section_index].PointerToRawData
  assert section_headers[debug_section_index].PointerToRelocations == 0
  assert section_headers[debug_section_index].PointerToLineNumbers == 0
  assert section_headers[debug_section_index].NumberOfRelocations == 0
  assert section_headers[debug_section_index].NumberOfLineNumbers == 0

  # Make sure sections in front of .debug$S have their data preceding it.
  for header in section_headers[:debug_section_index]:
    assert header.PointerToRawData < debug_offset
    assert header.PointerToRelocations < debug_offset
    assert header.PointerToLineNumbers < debug_offset

  # Make sure sections after of .debug$S have their data following it.
  for header in section_headers[debug_section_index + 1:]:
    # Make sure the .debug$S data is at the very end of section data:
    assert header.PointerToRawData > debug_offset
    assert header.PointerToRelocations == 0
    assert header.PointerToLineNumbers == 0

  # Make sure the first non-empty section's data starts right after the section
  # headers.
  for section_header in section_headers:
    if section_header.PointerToRawData == 0:
      assert section_header.PointerToRelocations == 0
      assert section_header.PointerToLineNumbers == 0
      continue
    assert section_header.PointerToRawData == data_start
    break

  # Make sure the symbol table (and hence, string table) appear after the last
  # section:
  assert (
      coff_header.PointerToSymbolTable >=
      section_headers[-1].PointerToRawData + section_headers[-1].SizeOfRawData)

  # The symbol table contains a symbol for the no-longer-present .debug$S
  # section. If we leave it there, lld-link will complain:
  #
  #    lld-link: error: .debug$S should not refer to non-existent section 5
  #
  # so we need to remove that symbol table entry as well. This shifts symbol
  # entries around and we need to update symbol table indices in:
  # - relocations
  # - line number records (never present)
  # - one aux symbol entry (IMAGE_SYM_CLASS_CLR_TOKEN; not present in ml output)
  SYM = Struct(
      'SYM',
      '8s',
      'Name',
      'I',
      'Value',
      'h',
      'SectionNumber',  # Note: Signed!
      'H',
      'Type',
      'B',
      'StorageClass',
      'B',
      'NumberOfAuxSymbols')
  i = 0
  debug_sym = -1
  while i < coff_header.NumberOfSymbols:
    sym_offset = coff_header.PointerToSymbolTable + i * SYM.size()
    sym = SYM.unpack_from(objdata, sym_offset)

    # 107 is IMAGE_SYM_CLASS_CLR_TOKEN, which has aux entry "CLR Token
    # Definition", which contains a symbol index. Check it's never present.
    assert sym.StorageClass != 107

    # Note: sym.SectionNumber is 1-based, debug_section_index is 0-based.
    if sym.SectionNumber - 1 == debug_section_index:
      assert debug_sym == -1, 'more than one .debug$S symbol found'
      debug_sym = i
      # Make sure the .debug$S symbol looks like we expect.
      # In particular, it should have exactly one aux symbol.
      assert sym.Name == b'.debug$S'
      assert sym.Value == 0
      assert sym.Type == 0
      assert sym.StorageClass == 3
      assert sym.NumberOfAuxSymbols == 1
    elif sym.SectionNumber > debug_section_index:
      sym = Subtract(sym, SectionNumber=1)
      SYM.pack_into(objdata, sym_offset, sym)
    i += 1 + sym.NumberOfAuxSymbols
  assert debug_sym != -1, '.debug$S symbol not found'

  # Note: Usually the .debug$S section is the last, but for files saying
  # `includelib foo.lib`, like safe_terminate_process.asm in 32-bit builds,
  # this isn't true: .drectve is after .debug$S.

  # Update symbol table indices in relocations.
  # There are a few processor types that have one or two relocation types
  # where SymbolTableIndex has a different meaning, but not for x86.
  REL = Struct('REL', 'I', 'VirtualAddress', 'I', 'SymbolTableIndex', 'H',
               'Type')
  for header in section_headers[0:debug_section_index]:
    for j in range(0, header.NumberOfRelocations):
      rel_offset = header.PointerToRelocations + j * REL.size()
      rel = REL.unpack_from(objdata, rel_offset)
      assert rel.SymbolTableIndex != debug_sym
      if rel.SymbolTableIndex > debug_sym:
        rel = Subtract(rel, SymbolTableIndex=2)
        REL.pack_into(objdata, rel_offset, rel)

  # Update symbol table indices in line numbers -- just check they don't exist.
  for header in section_headers:
    assert header.NumberOfLineNumbers == 0

  # Now that all indices are updated, remove the symbol table entry referring to
  # .debug$S and its aux entry.
  del objdata[coff_header.PointerToSymbolTable +
              debug_sym * SYM.size():coff_header.PointerToSymbolTable +
              (debug_sym + 2) * SYM.size()]

  # Now we know that it's safe to write out the input data, with just the
  # timestamp overwritten to 0, the last section header cut out (and the
  # offsets of all other section headers decremented by the size of that
  # one section header), and the last section's data cut out. The symbol
  # table offset needs to be reduced by one section header and the size of
  # the missing section.
  # (The COFF spec only requires on-disk sections to be aligned in image files,
  # for obj files it's not required. If that wasn't the case, deleting slices
  # if data would not generally be safe.)

  # Update section offsets and remove .debug$S section data.
  for i in range(0, debug_section_index):
    header = section_headers[i]
    if header.SizeOfRawData:
      header = Subtract(header, PointerToRawData=SECTIONHEADER.size())
    if header.NumberOfRelocations:
      header = Subtract(header, PointerToRelocations=SECTIONHEADER.size())
    if header.NumberOfLineNumbers:
      header = Subtract(header, PointerToLineNumbers=SECTIONHEADER.size())
    SECTIONHEADER.pack_into(objdata,
                            COFFHEADER.size() + i * SECTIONHEADER.size(),
                            header)
  for i in range(debug_section_index + 1, len(section_headers)):
    header = section_headers[i]
    shift = SECTIONHEADER.size() + debug_size
    if header.SizeOfRawData:
      header = Subtract(header, PointerToRawData=shift)
    if header.NumberOfRelocations:
      header = Subtract(header, PointerToRelocations=shift)
    if header.NumberOfLineNumbers:
      header = Subtract(header, PointerToLineNumbers=shift)
    SECTIONHEADER.pack_into(objdata,
                            COFFHEADER.size() + i * SECTIONHEADER.size(),
                            header)

  del objdata[debug_offset:debug_offset + debug_size]

  # Finally, remove .debug$S section header and update coff header.
  coff_header = coff_header._replace(TimeDateStamp=0)
  coff_header = Subtract(coff_header,
                         NumberOfSections=1,
                         PointerToSymbolTable=SECTIONHEADER.size() + debug_size,
                         NumberOfSymbols=2)
  COFFHEADER.pack_into(objdata, 0, coff_header)

  del objdata[COFFHEADER.size() +
              debug_section_index * SECTIONHEADER.size():COFFHEADER.size() +
              (debug_section_index + 1) * SECTIONHEADER.size()]

  # All done!
  if sys.version_info.major == 2:
    return objdata.tostring()
  else:
    return objdata.tobytes()


def main():
  ml_result = subprocess.call(sys.argv[1:])
  if ml_result != 0:
    return ml_result

  objfile = None
  for i in range(1, len(sys.argv)):
    if sys.argv[i].startswith('/Fo'):
      objfile = sys.argv[i][len('/Fo'):]
  assert objfile, 'failed to find ml output'

  with open(objfile, 'rb') as f:
    objdata = f.read()
  objdata = MakeDeterministic(objdata)
  with open(objfile, 'wb') as f:
    f.write(objdata)


if __name__ == '__main__':
  sys.exit(main())
