11cb0ef41Sopenharmony_ci#!/usr/bin/env python
21cb0ef41Sopenharmony_ci#
31cb0ef41Sopenharmony_ci# Copyright 2011 the V8 project authors. All rights reserved.
41cb0ef41Sopenharmony_ci# Redistribution and use in source and binary forms, with or without
51cb0ef41Sopenharmony_ci# modification, are permitted provided that the following conditions are
61cb0ef41Sopenharmony_ci# met:
71cb0ef41Sopenharmony_ci#
81cb0ef41Sopenharmony_ci#     * Redistributions of source code must retain the above copyright
91cb0ef41Sopenharmony_ci#       notice, this list of conditions and the following disclaimer.
101cb0ef41Sopenharmony_ci#     * Redistributions in binary form must reproduce the above
111cb0ef41Sopenharmony_ci#       copyright notice, this list of conditions and the following
121cb0ef41Sopenharmony_ci#       disclaimer in the documentation and/or other materials provided
131cb0ef41Sopenharmony_ci#       with the distribution.
141cb0ef41Sopenharmony_ci#     * Neither the name of Google Inc. nor the names of its
151cb0ef41Sopenharmony_ci#       contributors may be used to endorse or promote products derived
161cb0ef41Sopenharmony_ci#       from this software without specific prior written permission.
171cb0ef41Sopenharmony_ci#
181cb0ef41Sopenharmony_ci# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
191cb0ef41Sopenharmony_ci# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
201cb0ef41Sopenharmony_ci# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
211cb0ef41Sopenharmony_ci# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
221cb0ef41Sopenharmony_ci# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
231cb0ef41Sopenharmony_ci# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
241cb0ef41Sopenharmony_ci# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
251cb0ef41Sopenharmony_ci# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
261cb0ef41Sopenharmony_ci# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
271cb0ef41Sopenharmony_ci# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
281cb0ef41Sopenharmony_ci# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciimport os
311cb0ef41Sopenharmony_ciimport re
321cb0ef41Sopenharmony_ciimport subprocess
331cb0ef41Sopenharmony_ciimport tempfile
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci# Avoid using the slow (google-specific) wrapper around objdump.
371cb0ef41Sopenharmony_ciOBJDUMP_BIN = "/usr/bin/objdump"
381cb0ef41Sopenharmony_ciif not os.path.exists(OBJDUMP_BIN):
391cb0ef41Sopenharmony_ci  OBJDUMP_BIN = "objdump"
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci# -M intel-mnemonic selects Intel syntax.
421cb0ef41Sopenharmony_ci# -C demangles.
431cb0ef41Sopenharmony_ci# -z disables skipping over sections of zeroes.
441cb0ef41Sopenharmony_ci_COMMON_DISASM_OPTIONS = ["-M", "intel-mnemonic", "-C", "-z"]
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci_DISASM_HEADER_RE = re.compile(r"[a-f0-9]+\s+<.*:$")
471cb0ef41Sopenharmony_ci_DISASM_LINE_RE = re.compile(r"\s*([a-f0-9]+):\s*(\S.*)")
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci# Keys must match constants in Logger::LogCodeInfo.
501cb0ef41Sopenharmony_ci_ARCH_MAP = {
511cb0ef41Sopenharmony_ci  "ia32": "-m i386",
521cb0ef41Sopenharmony_ci  "x64": "-m i386 -M x86-64",
531cb0ef41Sopenharmony_ci  "arm": "-m arm",  # Not supported by our objdump build.
541cb0ef41Sopenharmony_ci  "mips": "-m mips",  # Not supported by our objdump build.
551cb0ef41Sopenharmony_ci  "arm64": "-m aarch64"
561cb0ef41Sopenharmony_ci}
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_cidef GetDisasmLines(filename, offset, size, arch, inplace, arch_flags=""):
601cb0ef41Sopenharmony_ci  tmp_name = None
611cb0ef41Sopenharmony_ci  if not inplace:
621cb0ef41Sopenharmony_ci    # Create a temporary file containing a copy of the code.
631cb0ef41Sopenharmony_ci    assert arch in _ARCH_MAP, "Unsupported architecture '%s'" % arch
641cb0ef41Sopenharmony_ci    arch_flags = arch_flags + " " +  _ARCH_MAP[arch]
651cb0ef41Sopenharmony_ci    tmp_file = tempfile.NamedTemporaryFile(prefix=".v8code", delete=False)
661cb0ef41Sopenharmony_ci    tmp_name = tmp_file.name
671cb0ef41Sopenharmony_ci    tmp_file.close()
681cb0ef41Sopenharmony_ci    command = "dd if=%s of=%s bs=1 count=%d skip=%d && " \
691cb0ef41Sopenharmony_ci              "%s %s -D -b binary %s %s" % (
701cb0ef41Sopenharmony_ci      filename, tmp_name, size, offset,
711cb0ef41Sopenharmony_ci      OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags,
721cb0ef41Sopenharmony_ci      tmp_name)
731cb0ef41Sopenharmony_ci  else:
741cb0ef41Sopenharmony_ci    command = "%s %s %s --start-address=%d --stop-address=%d -d %s " % (
751cb0ef41Sopenharmony_ci      OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags,
761cb0ef41Sopenharmony_ci      offset,
771cb0ef41Sopenharmony_ci      offset + size,
781cb0ef41Sopenharmony_ci      filename)
791cb0ef41Sopenharmony_ci  process = subprocess.Popen(command,
801cb0ef41Sopenharmony_ci                             shell=True,
811cb0ef41Sopenharmony_ci                             stdout=subprocess.PIPE,
821cb0ef41Sopenharmony_ci                             stderr=subprocess.STDOUT)
831cb0ef41Sopenharmony_ci  out, err = process.communicate()
841cb0ef41Sopenharmony_ci  lines = out.decode('utf-8').split("\n")
851cb0ef41Sopenharmony_ci  header_line = 0
861cb0ef41Sopenharmony_ci  for i, line in enumerate(lines):
871cb0ef41Sopenharmony_ci    if _DISASM_HEADER_RE.match(line):
881cb0ef41Sopenharmony_ci      header_line = i
891cb0ef41Sopenharmony_ci      break
901cb0ef41Sopenharmony_ci  if tmp_name:
911cb0ef41Sopenharmony_ci    os.unlink(tmp_name)
921cb0ef41Sopenharmony_ci  split_lines = []
931cb0ef41Sopenharmony_ci  for line in lines[header_line + 1:]:
941cb0ef41Sopenharmony_ci    match = _DISASM_LINE_RE.match(line)
951cb0ef41Sopenharmony_ci    if match:
961cb0ef41Sopenharmony_ci      line_address = int(match.group(1), 16)
971cb0ef41Sopenharmony_ci      split_lines.append((line_address, match.group(2)))
981cb0ef41Sopenharmony_ci  return split_lines
99