13a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org#!/usr/bin/env python 23a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# 33a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# Copyright 2011 the V8 project authors. All rights reserved. 43a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# Redistribution and use in source and binary forms, with or without 53a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# modification, are permitted provided that the following conditions are 63a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# met: 73a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# 83a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# * Redistributions of source code must retain the above copyright 93a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# notice, this list of conditions and the following disclaimer. 103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# * Redistributions in binary form must reproduce the above 113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# copyright notice, this list of conditions and the following 123a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# disclaimer in the documentation and/or other materials provided 133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# with the distribution. 143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# * Neither the name of Google Inc. nor the names of its 153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# contributors may be used to endorse or promote products derived 163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# from this software without specific prior written permission. 173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# 183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgimport os 313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgimport re 323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgimport subprocess 333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgimport tempfile 343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# Avoid using the slow (google-specific) wrapper around objdump. 373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgOBJDUMP_BIN = "/usr/bin/objdump" 383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgif not os.path.exists(OBJDUMP_BIN): 393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org OBJDUMP_BIN = "objdump" 403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org_COMMON_DISASM_OPTIONS = ["-M", "intel-mnemonic", "-C"] 433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org_DISASM_HEADER_RE = re.compile(r"[a-f0-9]+\s+<.*:$") 453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org_DISASM_LINE_RE = re.compile(r"\s*([a-f0-9]+):\s*(\S.*)") 463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org# Keys must match constants in Logger::LogCodeInfo. 483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org_ARCH_MAP = { 493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org "ia32": "-m i386", 503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org "x64": "-m i386 -M x86-64", 5156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org "arm": "-m arm", # Not supported by our objdump build. 5208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org "mips": "-m mips", # Not supported by our objdump build. 5308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org "arm64": "-m aarch64" 543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 5759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgdef GetDisasmLines(filename, offset, size, arch, inplace, arch_flags=""): 583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org tmp_name = None 593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if not inplace: 603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org # Create a temporary file containing a copy of the code. 613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org assert arch in _ARCH_MAP, "Unsupported architecture '%s'" % arch 6259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org arch_flags = arch_flags + " " + _ARCH_MAP[arch] 633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org tmp_name = tempfile.mktemp(".v8code") 643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org command = "dd if=%s of=%s bs=1 count=%d skip=%d && " \ 653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org "%s %s -D -b binary %s %s" % ( 663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org filename, tmp_name, size, offset, 673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags, 683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org tmp_name) 693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org else: 7059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org command = "%s %s %s --start-address=%d --stop-address=%d -d %s " % ( 7159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags, 723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org offset, 733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org offset + size, 743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org filename) 753a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org process = subprocess.Popen(command, 763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org shell=True, 773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org stdout=subprocess.PIPE, 783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org stderr=subprocess.STDOUT) 793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org out, err = process.communicate() 803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org lines = out.split("\n") 813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org header_line = 0 823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org for i, line in enumerate(lines): 833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if _DISASM_HEADER_RE.match(line): 843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org header_line = i 853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org break 863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if tmp_name: 873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org os.unlink(tmp_name) 883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org split_lines = [] 893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org for line in lines[header_line + 1:]: 903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org match = _DISASM_LINE_RE.match(line) 913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if match: 923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org line_address = int(match.group(1), 16) 933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org split_lines.append((line_address, match.group(2))) 943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return split_lines 95