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