1e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#!/usr/bin/env python
2e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#
3e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# Copyright 2011 the V8 project authors. All rights reserved.
4e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# Redistribution and use in source and binary forms, with or without
5e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# modification, are permitted provided that the following conditions are
6e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# met:
7e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#
8e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#     * Redistributions of source code must retain the above copyright
9e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#       notice, this list of conditions and the following disclaimer.
10e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#     * Redistributions in binary form must reproduce the above
11e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#       copyright notice, this list of conditions and the following
12e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#       disclaimer in the documentation and/or other materials provided
13e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#       with the distribution.
14e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#     * Neither the name of Google Inc. nor the names of its
15e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#       contributors may be used to endorse or promote products derived
16e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#       from this software without specific prior written permission.
17e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#
18e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
30e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport os
31e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport re
32e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport subprocess
33e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport tempfile
34e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
35e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
36e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# Avoid using the slow (google-specific) wrapper around objdump.
37e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochOBJDUMP_BIN = "/usr/bin/objdump"
38e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochif not os.path.exists(OBJDUMP_BIN):
39e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  OBJDUMP_BIN = "objdump"
40e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
41e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
42e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch_COMMON_DISASM_OPTIONS = ["-M", "intel-mnemonic", "-C"]
43e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
44e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch_DISASM_HEADER_RE = re.compile(r"[a-f0-9]+\s+<.*:$")
45e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch_DISASM_LINE_RE = re.compile(r"\s*([a-f0-9]+):\s*(\S.*)")
46e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
47e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# Keys must match constants in Logger::LogCodeInfo.
48e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch_ARCH_MAP = {
49e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  "ia32": "-m i386",
50e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  "x64": "-m i386 -M x86-64",
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  "arm": "-m arm",  # Not supported by our objdump build.
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  "mips": "-m mips",  # Not supported by our objdump build.
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  "arm64": "-m aarch64"
54e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
55e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
56e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef GetDisasmLines(filename, offset, size, arch, inplace, arch_flags=""):
58e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  tmp_name = None
59e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  if not inplace:
60e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    # Create a temporary file containing a copy of the code.
61e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    assert arch in _ARCH_MAP, "Unsupported architecture '%s'" % arch
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arch_flags = arch_flags + " " +  _ARCH_MAP[arch]
63e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    tmp_name = tempfile.mktemp(".v8code")
64e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    command = "dd if=%s of=%s bs=1 count=%d skip=%d && " \
65e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch              "%s %s -D -b binary %s %s" % (
66e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      filename, tmp_name, size, offset,
67e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags,
68e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      tmp_name)
69e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  else:
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    command = "%s %s %s --start-address=%d --stop-address=%d -d %s " % (
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags,
72e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      offset,
73e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      offset + size,
74e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      filename)
75e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  process = subprocess.Popen(command,
76e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                             shell=True,
77e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                             stdout=subprocess.PIPE,
78e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                             stderr=subprocess.STDOUT)
79e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  out, err = process.communicate()
80e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  lines = out.split("\n")
81e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  header_line = 0
82e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  for i, line in enumerate(lines):
83e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    if _DISASM_HEADER_RE.match(line):
84e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      header_line = i
85e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break
86e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  if tmp_name:
87e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    os.unlink(tmp_name)
88e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  split_lines = []
89e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  for line in lines[header_line + 1:]:
90e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    match = _DISASM_LINE_RE.match(line)
91e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    if match:
92e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      line_address = int(match.group(1), 16)
93e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      split_lines.append((line_address, match.group(2)))
94e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  return split_lines
95