llvm-project/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

185 lines
6.1 KiB
Python
Raw Normal View History

""" This module contains functions used by the test cases to hide the
architecture and/or the platform dependent nature of the tests. """
from __future__ import absolute_import
# System modules
import itertools
import re
import subprocess
import sys
import os
# Third-party modules
import six
from six.moves.urllib import parse as urlparse
# LLDB modules
from . import configuration
import lldb
import lldbsuite.test.lldbplatform as lldbplatform
def check_first_register_readable(test_case):
arch = test_case.getArchitecture()
if arch in ['x86_64', 'i386']:
test_case.expect("register read eax", substrs=['eax = 0x'])
elif arch in ['arm', 'armv7', 'armv7k', 'armv8l', 'armv7l']:
test_case.expect("register read r0", substrs=['r0 = 0x'])
elif arch in ['aarch64', 'arm64', 'arm64e', 'arm64_32']:
test_case.expect("register read x0", substrs=['x0 = 0x'])
elif re.match("mips", arch):
test_case.expect("register read zero", substrs=['zero = 0x'])
Support Linux on SystemZ as platform This patch adds support for Linux on SystemZ: - A new ArchSpec value of eCore_s390x_generic - A new directory Plugins/ABI/SysV-s390x providing an ABI implementation - Register context support - Native Linux support including watchpoint support - ELF core file support - Misc. support throughout the code base (e.g. breakpoint opcodes) - Test case updates to support the platform This should provide complete support for debugging the SystemZ platform. Not yet supported are optional features like transaction support (zEC12) or SIMD vector support (z13). There is no instruction emulation, since our ABI requires that all code provide correct DWARF CFI at all PC locations in .eh_frame to support unwinding (i.e. -fasynchronous-unwind-tables is on by default). The implementation follows existing platforms in a mostly straightforward manner. A couple of things that are different: - We do not use PTRACE_PEEKUSER / PTRACE_POKEUSER to access single registers, since some registers (access register) reside at offsets in the user area that are multiples of 4, but the PTRACE_PEEKUSER interface only allows accessing aligned 8-byte blocks in the user area. Instead, we use a s390 specific ptrace interface PTRACE_PEEKUSR_AREA / PTRACE_POKEUSR_AREA that allows accessing a whole block of the user area in one go, so in effect allowing to treat parts of the user area as register sets. - SystemZ hardware does not provide any means to implement read watchpoints, only write watchpoints. In fact, we can only support a *single* write watchpoint (but this can span a range of arbitrary size). In LLDB this means we support only a single watchpoint. I've set all test cases that require read watchpoints (or multiple watchpoints) to expected failure on the platform. [ Note that there were two test cases that install a read/write watchpoint even though they nowhere rely on the "read" property. I've changed those to simply use plain write watchpoints. ] Differential Revision: http://reviews.llvm.org/D18978 llvm-svn: 266308
2016-04-14 22:28:34 +08:00
elif arch in ['s390x']:
test_case.expect("register read r0", substrs=['r0 = 0x'])
elif arch in ['powerpc64le']:
test_case.expect("register read r0", substrs=['r0 = 0x'])
else:
# TODO: Add check for other architectures
test_case.fail(
"Unsupported architecture for test case (arch: %s)" %
test_case.getArchitecture())
def _run_adb_command(cmd, device_id):
device_id_args = []
if device_id:
device_id_args = ["-s", device_id]
full_cmd = ["adb"] + device_id_args + cmd
p = subprocess.Popen(
full_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
return p.returncode, stdout, stderr
def target_is_android():
if not hasattr(target_is_android, 'result'):
triple = lldb.DBG.GetSelectedPlatform().GetTriple()
match = re.match(".*-.*-.*-android", triple)
target_is_android.result = match is not None
return target_is_android.result
def android_device_api():
if not hasattr(android_device_api, 'result'):
assert configuration.lldb_platform_url is not None
device_id = None
parsed_url = urlparse.urlparse(configuration.lldb_platform_url)
host_name = parsed_url.netloc.split(":")[0]
if host_name != 'localhost':
device_id = host_name
if device_id.startswith('[') and device_id.endswith(']'):
device_id = device_id[1:-1]
retcode, stdout, stderr = _run_adb_command(
["shell", "getprop", "ro.build.version.sdk"], device_id)
if retcode == 0:
android_device_api.result = int(stdout)
else:
raise LookupError(
">>> Unable to determine the API level of the Android device.\n"
">>> stdout:\n%s\n"
">>> stderr:\n%s\n" %
(stdout, stderr))
return android_device_api.result
def match_android_device(device_arch, valid_archs=None, valid_api_levels=None):
if not target_is_android():
return False
if valid_archs is not None and device_arch not in valid_archs:
return False
if valid_api_levels is not None and android_device_api() not in valid_api_levels:
return False
return True
def finalize_build_dictionary(dictionary):
if target_is_android():
if dictionary is None:
dictionary = {}
dictionary["OS"] = "Android"
dictionary["PIE"] = 1
return dictionary
def getHostPlatform():
"""Returns the host platform running the test suite."""
# Attempts to return a platform name matching a target Triple platform.
if sys.platform.startswith('linux'):
return 'linux'
elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
return 'windows'
elif sys.platform.startswith('darwin'):
return 'darwin'
elif sys.platform.startswith('freebsd'):
return 'freebsd'
elif sys.platform.startswith('netbsd'):
return 'netbsd'
else:
return sys.platform
def getDarwinOSTriples():
return ['darwin', 'macosx', 'ios', 'watchos', 'tvos', 'bridgeos']
def getPlatform():
"""Returns the target platform which the tests are running on."""
platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
if platform.startswith('freebsd'):
platform = 'freebsd'
elif platform.startswith('netbsd'):
platform = 'netbsd'
return platform
def platformIsDarwin():
"""Returns true if the OS triple for the selected platform is any valid apple OS"""
return getPlatform() in getDarwinOSTriples()
def findMainThreadCheckerDylib():
if not platformIsDarwin():
return ""
if getPlatform() in lldbplatform.translate(lldbplatform.darwin_embedded):
return "/Developer/usr/lib/libMainThreadChecker.dylib"
with os.popen('xcode-select -p') as output:
xcode_developer_path = output.read().strip()
mtc_dylib_path = '%s/usr/lib/libMainThreadChecker.dylib' % xcode_developer_path
if os.path.isfile(mtc_dylib_path):
return mtc_dylib_path
return ""
class _PlatformContext(object):
"""Value object class which contains platform-specific options."""
def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
self.shlib_environment_var = shlib_environment_var
self.shlib_prefix = shlib_prefix
self.shlib_extension = shlib_extension
def createPlatformContext():
if platformIsDarwin():
return _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
elif getPlatform() in ("freebsd", "linux", "netbsd"):
return _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
else:
return None
def hasChattyStderr(test_case):
"""Some targets produce garbage on the standard error output. This utility function
determines whether the tests can be strict about the expected stderr contents."""
if match_android_device(test_case.getArchitecture(), ['aarch64'], range(22, 25+1)):
return True # The dynamic linker on the device will complain about unknown DT entries
return False