diff --git a/packages/Python/lldbsuite/test/functionalities/register/register_command/TestRegisters.py b/packages/Python/lldbsuite/test/functionalities/register/register_command/TestRegisters.py index cc1389ca6b01..fe6ce2c25a3e 100644 --- a/packages/Python/lldbsuite/test/functionalities/register/register_command/TestRegisters.py +++ b/packages/Python/lldbsuite/test/functionalities/register/register_command/TestRegisters.py @@ -1,429 +1,429 @@ """ Test the 'register' command. """ from __future__ import print_function import os import sys import time import re import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil class RegisterCommandsTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) NO_DEBUG_INFO_TESTCASE = True def setUp(self): TestBase.setUp(self) self.has_teardown = False def tearDown(self): self.dbg.GetSelectedTarget().GetProcess().Destroy() TestBase.tearDown(self) @skipIfiOSSimulator @skipIf(archs=no_match(['amd64', 'arm', 'i386', 'x86_64'])) def test_register_commands(self): """Test commands related to registers, in particular vector registers.""" self.build() self.common_setup() # verify that logging does not assert self.log_enable("registers") self.expect("register read -a", MISSING_EXPECTED_REGISTERS, substrs=['registers were unavailable'], matching=False) if self.getArchitecture() in ['amd64', 'i386', 'x86_64']: self.runCmd("register read xmm0") self.runCmd("register read ymm15") # may be available self.runCmd("register read bnd0") # may be available elif self.getArchitecture() in ['arm']: self.runCmd("register read s0") self.runCmd("register read q15") # may be available self.expect( "register read -s 4", substrs=['invalid register set index: 4'], error=True) @skipIfiOSSimulator # Writing of mxcsr register fails, presumably due to a kernel/hardware # problem @skipIfTargetAndroid(archs=["i386"]) @skipIf(archs=no_match(['amd64', 'arm', 'i386', 'x86_64'])) def test_fp_register_write(self): """Test commands that write to registers, in particular floating-point registers.""" self.build() self.fp_register_write() @skipIfiOSSimulator # "register read fstat" always return 0xffff @expectedFailureAndroid(archs=["i386"]) @skipIfFreeBSD # llvm.org/pr25057 @skipIf(archs=no_match(['amd64', 'i386', 'x86_64'])) def test_fp_special_purpose_register_read(self): """Test commands that read fpu special purpose registers.""" self.build() self.fp_special_purpose_register_read() @skipIfiOSSimulator @skipIf(archs=no_match(['amd64', 'arm', 'i386', 'x86_64'])) def test_register_expressions(self): """Test expression evaluation with commands related to registers.""" self.build() self.common_setup() if self.getArchitecture() in ['amd64', 'i386', 'x86_64']: gpr = "eax" vector = "xmm0" elif self.getArchitecture() in ['arm']: gpr = "r0" vector = "q0" self.expect("expr/x $%s" % gpr, substrs=['unsigned int', ' = 0x']) self.expect("expr $%s" % vector, substrs=['vector_type']) self.expect( "expr (unsigned int)$%s[0]" % vector, substrs=['unsigned int']) if self.getArchitecture() in ['amd64', 'x86_64']: self.expect( "expr -- ($rax & 0xffffffff) == $eax", substrs=['true']) @skipIfiOSSimulator @skipIf(archs=no_match(['amd64', 'x86_64'])) def test_convenience_registers(self): """Test convenience registers.""" self.build() self.convenience_registers() @skipIfiOSSimulator @skipIf(archs=no_match(['amd64', 'x86_64'])) def test_convenience_registers_with_process_attach(self): """Test convenience registers after a 'process attach'.""" self.build() self.convenience_registers_with_process_attach(test_16bit_regs=False) @skipIfiOSSimulator @skipIf(archs=no_match(['amd64', 'x86_64'])) def test_convenience_registers_16bit_with_process_attach(self): """Test convenience registers after a 'process attach'.""" self.build() self.convenience_registers_with_process_attach(test_16bit_regs=True) def common_setup(self): exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break in main(). lldbutil.run_break_set_by_symbol( self, "main", num_expected_locations=-1) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # platform specific logging of the specified category def log_enable(self, category): # This intentionally checks the host platform rather than the target # platform as logging is host side. self.platform = "" if (sys.platform.startswith("freebsd") or sys.platform.startswith("linux") or sys.platform.startswith("netbsd")): self.platform = "posix" if self.platform != "": self.log_file = os.path.join(os.getcwd(), 'TestRegisters.log') self.runCmd( "log enable " + self.platform + " " + str(category) + " registers -v -f " + self.log_file, RUN_SUCCEEDED) if not self.has_teardown: def remove_log(self): if os.path.exists(self.log_file): os.remove(self.log_file) self.has_teardown = True self.addTearDownHook(remove_log) def write_and_read(self, frame, register, new_value, must_exist=True): value = frame.FindValue(register, lldb.eValueTypeRegister) if must_exist: self.assertTrue( value.IsValid(), "finding a value for register " + register) elif not value.IsValid(): return # If register doesn't exist, skip this test self.runCmd("register write " + register + " \'" + new_value + "\'") self.expect( "register read " + register, substrs=[ register + ' = ', new_value]) def fp_special_purpose_register_read(self): exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Launch the process and stop. self.expect("run", PROCESS_STOPPED, substrs=['stopped']) # Check stop reason; Should be either signal SIGTRAP or EXC_BREAKPOINT output = self.res.GetOutput() matched = False substrs = [ 'stop reason = EXC_BREAKPOINT', 'stop reason = signal SIGTRAP'] for str1 in substrs: matched = output.find(str1) != -1 with recording(self, False) as sbuf: print("%s sub string: %s" % ('Expecting', str1), file=sbuf) print("Matched" if matched else "Not Matched", file=sbuf) if matched: break self.assertTrue(matched, STOPPED_DUE_TO_SIGNAL) process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = process.GetThreadAtIndex(0) self.assertTrue(thread.IsValid(), "current thread is valid") currentFrame = thread.GetFrameAtIndex(0) self.assertTrue(currentFrame.IsValid(), "current frame is valid") # Extract the value of fstat and ftag flag at the point just before # we start pushing floating point values on st% register stack value = currentFrame.FindValue("fstat", lldb.eValueTypeRegister) error = lldb.SBError() reg_value_fstat_initial = value.GetValueAsUnsigned(error, 0) self.assertTrue(error.Success(), "reading a value for fstat") value = currentFrame.FindValue("ftag", lldb.eValueTypeRegister) error = lldb.SBError() reg_value_ftag_initial = value.GetValueAsUnsigned(error, 0) self.assertTrue(error.Success(), "reading a value for ftag") fstat_top_pointer_initial = (reg_value_fstat_initial & 0x3800) >> 11 # Execute 'si' aka 'thread step-inst' instruction 5 times and with # every execution verify the value of fstat and ftag registers for x in range(0, 5): # step into the next instruction to push a value on 'st' register # stack self.runCmd("si", RUN_SUCCEEDED) # Verify fstat and save it to be used for verification in next # execution of 'si' command if not (reg_value_fstat_initial & 0x3800): self.expect("register read fstat", substrs=[ 'fstat' + ' = ', str("0x%0.4x" % ((reg_value_fstat_initial & ~(0x3800)) | 0x3800))]) reg_value_fstat_initial = ( (reg_value_fstat_initial & ~(0x3800)) | 0x3800) fstat_top_pointer_initial = 7 else: self.expect("register read fstat", substrs=[ 'fstat' + ' = ', str("0x%0.4x" % (reg_value_fstat_initial - 0x0800))]) reg_value_fstat_initial = (reg_value_fstat_initial - 0x0800) fstat_top_pointer_initial -= 1 # Verify ftag and save it to be used for verification in next # execution of 'si' command self.expect( "register read ftag", substrs=[ 'ftag' + ' = ', str( - "0x%0.2x" % + "0x%0.4x" % (reg_value_ftag_initial | ( 1 << fstat_top_pointer_initial)))]) reg_value_ftag_initial = reg_value_ftag_initial | ( 1 << fstat_top_pointer_initial) def fp_register_write(self): exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) lldbutil.run_break_set_by_symbol( self, "main", num_expected_locations=-1) # Launch the process, and do not stop at the entry point. process = target.LaunchSimple( None, None, self.get_process_working_directory()) process = target.GetProcess() self.assertTrue( process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) thread = process.GetThreadAtIndex(0) self.assertTrue(thread.IsValid(), "current thread is valid") currentFrame = thread.GetFrameAtIndex(0) self.assertTrue(currentFrame.IsValid(), "current frame is valid") if self.getArchitecture() in ['amd64', 'i386', 'x86_64']: reg_list = [ # reg value must-have ("fcw", "0x0000ff0e", False), ("fsw", "0x0000ff0e", False), ("ftw", "0x0000ff0e", False), ("ip", "0x0000ff0e", False), ("dp", "0x0000ff0e", False), ("mxcsr", "0x0000ff0e", False), ("mxcsrmask", "0x0000ff0e", False), ] st0regname = None if currentFrame.FindRegister("st0").IsValid(): st0regname = "st0" elif currentFrame.FindRegister("stmm0").IsValid(): st0regname = "stmm0" if st0regname is not None: # reg value # must-have reg_list.append( (st0regname, "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00}", True)) reg_list.append( ("xmm0", "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x2f 0x2f}", True)) reg_list.append( ("xmm15", "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f}", False)) elif self.getArchitecture() in ['arm']: reg_list = [ # reg value # must-have ("fpscr", "0xfbf79f9f", True), ("s0", "1.25", True), ("s31", "0.75", True), ("d1", "123", True), ("d17", "987", False), ("q1", "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x2f 0x2f}", True), ("q14", "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f}", False), ] for (reg, val, must) in reg_list: self.write_and_read(currentFrame, reg, val, must) if self.getArchitecture() in ['amd64', 'i386', 'x86_64']: self.runCmd( "register write " + st0regname + " \"{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}\"") self.expect( "register read " + st0regname + " --format f", substrs=[ st0regname + ' = 0']) has_avx = False has_mpx = False # Returns an SBValueList. registerSets = currentFrame.GetRegisters() for registerSet in registerSets: if 'advanced vector extensions' in registerSet.GetName().lower(): has_avx = True if 'memory protection extension' in registerSet.GetName().lower(): has_mpx = True if has_avx: new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0c 0x0d 0x0e 0x0f}" self.write_and_read(currentFrame, "ymm0", new_value) self.write_and_read(currentFrame, "ymm7", new_value) self.expect("expr $ymm0", substrs=['vector_type']) else: self.runCmd("register read ymm0") if has_mpx: # Test write and read for bnd0. new_value_w = "{0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10}" self.runCmd("register write bnd0 \'" + new_value_w + "\'") new_value_r = "{0x0807060504030201 0x100f0e0d0c0b0a09}" self.expect("register read bnd0", substrs = ['bnd0 = ', new_value_r]) self.expect("expr $bnd0", substrs = ['vector_type']) # Test write and for bndstatus. new_value = "{0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08}" self.write_and_read(currentFrame, "bndstatus", new_value) self.expect("expr $bndstatus", substrs = ['vector_type']) else: self.runCmd("register read bnd0") def convenience_registers(self): """Test convenience registers.""" self.common_setup() # The command "register read -a" does output a derived register like # eax... self.expect("register read -a", matching=True, substrs=['eax']) # ...however, the vanilla "register read" command should not output derived registers like eax. self.expect("register read", matching=False, substrs=['eax']) # Test reading of rax and eax. self.expect("register read rax eax", substrs=['rax = 0x', 'eax = 0x']) # Now write rax with a unique bit pattern and test that eax indeed # represents the lower half of rax. self.runCmd("register write rax 0x1234567887654321") self.expect("register read rax 0x1234567887654321", substrs=['0x1234567887654321']) def convenience_registers_with_process_attach(self, test_16bit_regs): """Test convenience registers after a 'process attach'.""" exe = os.path.join(os.getcwd(), "a.out") # Spawn a new process pid = self.spawnSubprocess(exe, ['wait_for_attach']).pid self.addTearDownHook(self.cleanupSubprocesses) if self.TraceOn(): print("pid of spawned process: %d" % pid) self.runCmd("process attach -p %d" % pid) # Check that "register read eax" works. self.runCmd("register read eax") if self.getArchitecture() in ['amd64', 'x86_64']: self.expect("expr -- ($rax & 0xffffffff) == $eax", substrs=['true']) if test_16bit_regs: self.expect("expr -- $ax == (($ah << 8) | $al)", substrs=['true']) diff --git a/source/Core/CMakeLists.txt b/source/Core/CMakeLists.txt index c5105bd9ab12..c345afb4064a 100644 --- a/source/Core/CMakeLists.txt +++ b/source/Core/CMakeLists.txt @@ -1,74 +1,84 @@ +set(LLDB_CURSES_LIBS) + +if (NOT LLDB_DISABLE_CURSES) + list(APPEND LLDB_CURSES_LIBS ${CURSES_LIBRARIES}) + if(LLVM_ENABLE_TERMINFO AND HAVE_TERMINFO) + list(APPEND LLDB_CURSES_LIBS ${TERMINFO_LIBS}) + endif() +endif() + add_lldb_library(lldbCore Address.cpp AddressRange.cpp AddressResolver.cpp AddressResolverFileLine.cpp AddressResolverName.cpp ArchSpec.cpp Broadcaster.cpp Communication.cpp Debugger.cpp Disassembler.cpp DumpDataExtractor.cpp DynamicLoader.cpp EmulateInstruction.cpp Event.cpp FileLineResolver.cpp FileSpecList.cpp FormatEntity.cpp IOHandler.cpp Listener.cpp Mangled.cpp Module.cpp ModuleChild.cpp ModuleList.cpp Opcode.cpp PluginManager.cpp RegisterValue.cpp Scalar.cpp SearchFilter.cpp Section.cpp SourceManager.cpp State.cpp StreamAsynchronousIO.cpp StreamFile.cpp UserSettingsController.cpp Value.cpp ValueObject.cpp ValueObjectCast.cpp ValueObjectChild.cpp ValueObjectConstResult.cpp ValueObjectConstResultCast.cpp ValueObjectConstResultChild.cpp ValueObjectConstResultImpl.cpp ValueObjectDynamicValue.cpp ValueObjectList.cpp ValueObjectMemory.cpp ValueObjectRegister.cpp ValueObjectSyntheticFilter.cpp ValueObjectVariable.cpp LINK_LIBS clangAST lldbBreakpoint lldbDataFormatters lldbExpression lldbHost lldbInterpreter lldbSymbol lldbTarget lldbUtility lldbPluginProcessUtility lldbPluginCPlusPlusLanguage lldbPluginObjCLanguage lldbPluginObjectFileJIT + ${LLDB_CURSES_LIBS} LINK_COMPONENTS BinaryFormat Support Demangle ) # Needed to properly resolve references in a debug build. # TODO: Remove once we have better layering set_target_properties(lldbCore PROPERTIES LINK_INTERFACE_MULTIPLICITY 4) diff --git a/source/Host/CMakeLists.txt b/source/Host/CMakeLists.txt index 2ee599cf43a2..1696e7eab6ea 100644 --- a/source/Host/CMakeLists.txt +++ b/source/Host/CMakeLists.txt @@ -1,177 +1,191 @@ macro(add_host_subdirectory group) list(APPEND HOST_SOURCES ${ARGN}) source_group(${group} FILES ${ARGN}) endmacro() add_host_subdirectory(common common/File.cpp common/FileCache.cpp common/FileSystem.cpp common/GetOptInc.cpp common/Host.cpp common/HostInfoBase.cpp common/HostNativeThreadBase.cpp common/HostProcess.cpp common/HostThread.cpp common/LockFileBase.cpp common/MainLoop.cpp common/MonitoringProcessLauncher.cpp common/NativeBreakpoint.cpp common/NativeBreakpointList.cpp common/NativeWatchpointList.cpp common/NativeProcessProtocol.cpp common/NativeRegisterContext.cpp common/NativeThreadProtocol.cpp common/OptionParser.cpp common/PipeBase.cpp common/ProcessRunLock.cpp common/PseudoTerminal.cpp common/Socket.cpp common/SocketAddress.cpp common/SoftwareBreakpoint.cpp common/StringConvert.cpp common/Symbols.cpp common/TCPSocket.cpp common/Terminal.cpp common/ThreadLauncher.cpp common/XML.cpp common/UDPSocket.cpp ) # Keep track of whether we want to provide a define for the # Python's architecture-specific lib path (i.e. where a # Python lldb module would go). set (get_python_libdir 0) if (NOT LLDB_DISABLE_LIBEDIT) add_host_subdirectory(common common/Editline.cpp ) endif() add_host_subdirectory(posix posix/ConnectionFileDescriptorPosix.cpp ) if(NOT LLDB_DISABLE_PYTHON) list(APPEND LLDB_PLUGINS lldbPluginScriptInterpreterPython) endif() if (CMAKE_SYSTEM_NAME MATCHES "Windows") add_host_subdirectory(windows windows/ConnectionGenericFileWindows.cpp windows/EditLineWin.cpp windows/FileSystem.cpp windows/Host.cpp windows/HostInfoWindows.cpp windows/HostProcessWindows.cpp windows/HostThreadWindows.cpp windows/LockFileWindows.cpp windows/PipeWindows.cpp windows/ProcessLauncherWindows.cpp windows/ProcessRunLock.cpp windows/Windows.cpp ) else() if (NOT LLDB_DISABLE_PYTHON) # We'll grab the arch-specific python libdir on POSIX systems. set (get_python_libdir 1) endif() add_host_subdirectory(posix posix/DomainSocket.cpp posix/FileSystem.cpp posix/HostInfoPosix.cpp posix/HostProcessPosix.cpp posix/HostThreadPosix.cpp posix/LockFilePosix.cpp posix/PipePosix.cpp posix/ProcessLauncherPosixFork.cpp ) if (CMAKE_SYSTEM_NAME MATCHES "Darwin") include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR}) add_host_subdirectory(macosx macosx/Host.mm macosx/HostInfoMacOSX.mm macosx/HostThreadMacOSX.mm macosx/Symbols.cpp macosx/cfcpp/CFCBundle.cpp macosx/cfcpp/CFCData.cpp macosx/cfcpp/CFCMutableArray.cpp macosx/cfcpp/CFCMutableDictionary.cpp macosx/cfcpp/CFCMutableSet.cpp macosx/cfcpp/CFCString.cpp ) if(IOS) set_property(SOURCE macosx/Host.mm APPEND PROPERTY COMPILE_DEFINITIONS "NO_XPC_SERVICES=1") endif() elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") add_host_subdirectory(linux linux/AbstractSocket.cpp linux/Host.cpp linux/HostInfoLinux.cpp linux/LibcGlue.cpp linux/Support.cpp ) if (CMAKE_SYSTEM_NAME MATCHES "Android") add_host_subdirectory(android android/HostInfoAndroid.cpp android/LibcGlue.cpp ) endif() elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") add_host_subdirectory(freebsd freebsd/Host.cpp freebsd/HostInfoFreeBSD.cpp ) elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") add_host_subdirectory(netbsd netbsd/Host.cpp netbsd/HostInfoNetBSD.cpp ) elseif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") add_host_subdirectory(openbsd openbsd/Host.cpp openbsd/HostInfoOpenBSD.cpp ) endif() endif() if (${get_python_libdir}) # Call a python script to gather the arch-specific libdir for # modules like the lldb module. execute_process( COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/get_relative_lib_dir.py RESULT_VARIABLE get_libdir_status OUTPUT_VARIABLE relative_libdir ) if (get_libdir_status EQUAL 0) add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}") endif() endif() +set(EXTRA_LIBS) if (CMAKE_SYSTEM_NAME MATCHES "NetBSD") - set(EXTRA_LIBS kvm) + list(APPEND EXTRA_LIBS kvm) endif () +if (APPLE) + list(APPEND EXTRA_LIBS xml2) +else () + if (LIBXML2_FOUND) + list(APPEND EXTRA_LIBS ${LIBXML2_LIBRARIES}) + endif() +endif () +if (HAVE_LIBDL) + list(APPEND EXTRA_LIBS ${CMAKE_DL_LIBS}) +endif() +if (NOT LLDB_DISABLE_LIBEDIT) + list(APPEND EXTRA_LIBS edit) +endif() add_lldb_library(lldbHost ${HOST_SOURCES} LINK_LIBS lldbCore lldbInterpreter lldbSymbol lldbTarget lldbUtility ${LLDB_PLUGINS} ${EXTRA_LIBS} LINK_COMPONENTS Support ) diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp index 6563796db12c..2cb17cb182e2 100644 --- a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp +++ b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp @@ -1,137 +1,136 @@ //===-- RegisterContextLinux_i386.cpp --------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===---------------------------------------------------------------------===// #include "RegisterContextLinux_i386.h" #include "RegisterContextPOSIX_x86.h" using namespace lldb_private; using namespace lldb; struct GPR { uint32_t ebx; uint32_t ecx; uint32_t edx; uint32_t esi; uint32_t edi; uint32_t ebp; uint32_t eax; uint32_t ds; uint32_t es; uint32_t fs; uint32_t gs; uint32_t orig_eax; uint32_t eip; uint32_t cs; uint32_t eflags; uint32_t esp; uint32_t ss; }; struct FPR_i386 { uint16_t fctrl; // FPU Control Word (fcw) uint16_t fstat; // FPU Status Word (fsw) - uint8_t ftag; // FPU Tag Word (ftw) - uint8_t reserved_1; // Reserved + uint16_t ftag; // FPU Tag Word (ftw) uint16_t fop; // Last Instruction Opcode (fop) union { struct { uint64_t fip; // Instruction Pointer uint64_t fdp; // Data Pointer } x86_64; struct { uint32_t fioff; // FPU IP Offset (fip) uint32_t fiseg; // FPU IP Selector (fcs) uint32_t fooff; // FPU Operand Pointer Offset (foo) uint32_t foseg; // FPU Operand Pointer Selector (fos) } i386_; // Added _ in the end to avoid error with gcc defining i386 in some // cases } ptr; uint32_t mxcsr; // MXCSR Register State uint32_t mxcsrmask; // MXCSR Mask MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes uint32_t padding[56]; }; struct UserArea { GPR regs; // General purpose registers. int32_t fpvalid; // True if FPU is being used. FPR_i386 i387; // FPU registers. uint32_t tsize; // Text segment size. uint32_t dsize; // Data segment size. uint32_t ssize; // Stack segment size. uint32_t start_code; // VM address of text. uint32_t start_stack; // VM address of stack bottom (top in rsp). int32_t signal; // Signal causing core dump. int32_t reserved; // Unused. uint32_t ar0; // Location of GPR's. uint32_t fpstate; // Location of FPR's. Should be a FXSTATE *, but this // has to be 32-bits even on 64-bit systems. uint32_t magic; // Identifier for core dumps. char u_comm[32]; // Command causing core dump. uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7). }; #define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0]) #define DR_0_OFFSET 0xFC #define DR_OFFSET(reg_index) (DR_0_OFFSET + (reg_index * 4)) #define FPR_SIZE(reg) sizeof(((FPR_i386 *)NULL)->reg) //--------------------------------------------------------------------------- // Include RegisterInfos_i386 to declare our g_register_infos_i386 structure. //--------------------------------------------------------------------------- #define DECLARE_REGISTER_INFOS_I386_STRUCT #include "RegisterInfos_i386.h" #undef DECLARE_REGISTER_INFOS_I386_STRUCT RegisterContextLinux_i386::RegisterContextLinux_i386( const ArchSpec &target_arch) : RegisterInfoInterface(target_arch) { RegisterInfo orig_ax = {"orig_eax", NULL, sizeof(((GPR *)NULL)->orig_eax), (LLVM_EXTENSION offsetof(GPR, orig_eax)), eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}; d_register_infos.push_back(orig_ax); } size_t RegisterContextLinux_i386::GetGPRSize() const { return sizeof(GPR); } const RegisterInfo *RegisterContextLinux_i386::GetRegisterInfo() const { switch (m_target_arch.GetMachine()) { case llvm::Triple::x86: case llvm::Triple::x86_64: return g_register_infos_i386; default: assert(false && "Unhandled target architecture."); return NULL; } } uint32_t RegisterContextLinux_i386::GetRegisterCount() const { return static_cast(sizeof(g_register_infos_i386) / sizeof(g_register_infos_i386[0])); } uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const { return static_cast(k_num_user_registers_i386); } const std::vector * RegisterContextLinux_i386::GetDynamicRegisterInfoP() const { return &d_register_infos; } diff --git a/source/Plugins/Process/Utility/RegisterContext_x86.h b/source/Plugins/Process/Utility/RegisterContext_x86.h index ab2ca2bb6c2c..5f6fc295a15c 100644 --- a/source/Plugins/Process/Utility/RegisterContext_x86.h +++ b/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -1,359 +1,358 @@ //===-- RegisterContext_x86.h -----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef liblldb_RegisterContext_x86_H_ #define liblldb_RegisterContext_x86_H_ #include #include #include "llvm/Support/Compiler.h" //--------------------------------------------------------------------------- // i386 ehframe, dwarf regnums //--------------------------------------------------------------------------- // Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems // (non-Darwin) // enum { ehframe_eax_i386 = 0, ehframe_ecx_i386, ehframe_edx_i386, ehframe_ebx_i386, // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus // dwarf's reg numbering). // To be specific: // i386+darwin eh_frame: 4 is ebp, 5 is esp // i386+everyone else eh_frame: 4 is esp, 5 is ebp // i386 dwarf: 4 is esp, 5 is ebp // lldb will get the darwin-specific eh_frame reg numberings from debugserver, // or the ABI, so we // only encode the generally correct 4 == esp, 5 == ebp numbers in this // generic header. ehframe_esp_i386, ehframe_ebp_i386, ehframe_esi_i386, ehframe_edi_i386, ehframe_eip_i386, ehframe_eflags_i386, ehframe_st0_i386 = 12, ehframe_st1_i386, ehframe_st2_i386, ehframe_st3_i386, ehframe_st4_i386, ehframe_st5_i386, ehframe_st6_i386, ehframe_st7_i386, ehframe_xmm0_i386 = 21, ehframe_xmm1_i386, ehframe_xmm2_i386, ehframe_xmm3_i386, ehframe_xmm4_i386, ehframe_xmm5_i386, ehframe_xmm6_i386, ehframe_xmm7_i386, ehframe_mm0_i386 = 29, ehframe_mm1_i386, ehframe_mm2_i386, ehframe_mm3_i386, ehframe_mm4_i386, ehframe_mm5_i386, ehframe_mm6_i386, ehframe_mm7_i386, }; // DWARF register numbers (eRegisterKindDWARF) // Intel's x86 or IA-32 enum { // General Purpose Registers. dwarf_eax_i386 = 0, dwarf_ecx_i386, dwarf_edx_i386, dwarf_ebx_i386, dwarf_esp_i386, dwarf_ebp_i386, dwarf_esi_i386, dwarf_edi_i386, dwarf_eip_i386, dwarf_eflags_i386, // Floating Point Registers dwarf_st0_i386 = 11, dwarf_st1_i386, dwarf_st2_i386, dwarf_st3_i386, dwarf_st4_i386, dwarf_st5_i386, dwarf_st6_i386, dwarf_st7_i386, // SSE Registers dwarf_xmm0_i386 = 21, dwarf_xmm1_i386, dwarf_xmm2_i386, dwarf_xmm3_i386, dwarf_xmm4_i386, dwarf_xmm5_i386, dwarf_xmm6_i386, dwarf_xmm7_i386, // MMX Registers dwarf_mm0_i386 = 29, dwarf_mm1_i386, dwarf_mm2_i386, dwarf_mm3_i386, dwarf_mm4_i386, dwarf_mm5_i386, dwarf_mm6_i386, dwarf_mm7_i386, dwarf_fctrl_i386 = 37, // x87 control word dwarf_fstat_i386 = 38, // x87 status word dwarf_mxcsr_i386 = 39, dwarf_es_i386 = 40, dwarf_cs_i386 = 41, dwarf_ss_i386 = 42, dwarf_ds_i386 = 43, dwarf_fs_i386 = 44, dwarf_gs_i386 = 45, // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and // then differentiate based on size of the register. dwarf_bnd0_i386 = 101, dwarf_bnd1_i386, dwarf_bnd2_i386, dwarf_bnd3_i386, }; //--------------------------------------------------------------------------- // AMD x86_64, AMD64, Intel EM64T, or Intel 64 ehframe, dwarf regnums //--------------------------------------------------------------------------- // EHFrame and DWARF Register numbers (eRegisterKindEHFrame & // eRegisterKindDWARF) // This is the spec I used (as opposed to x86-64-abi-0.99.pdf): // http://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf enum { // GP Registers dwarf_rax_x86_64 = 0, dwarf_rdx_x86_64, dwarf_rcx_x86_64, dwarf_rbx_x86_64, dwarf_rsi_x86_64, dwarf_rdi_x86_64, dwarf_rbp_x86_64, dwarf_rsp_x86_64, // Extended GP Registers dwarf_r8_x86_64 = 8, dwarf_r9_x86_64, dwarf_r10_x86_64, dwarf_r11_x86_64, dwarf_r12_x86_64, dwarf_r13_x86_64, dwarf_r14_x86_64, dwarf_r15_x86_64, // Return Address (RA) mapped to RIP dwarf_rip_x86_64 = 16, // SSE Vector Registers dwarf_xmm0_x86_64 = 17, dwarf_xmm1_x86_64, dwarf_xmm2_x86_64, dwarf_xmm3_x86_64, dwarf_xmm4_x86_64, dwarf_xmm5_x86_64, dwarf_xmm6_x86_64, dwarf_xmm7_x86_64, dwarf_xmm8_x86_64, dwarf_xmm9_x86_64, dwarf_xmm10_x86_64, dwarf_xmm11_x86_64, dwarf_xmm12_x86_64, dwarf_xmm13_x86_64, dwarf_xmm14_x86_64, dwarf_xmm15_x86_64, // Floating Point Registers dwarf_st0_x86_64 = 33, dwarf_st1_x86_64, dwarf_st2_x86_64, dwarf_st3_x86_64, dwarf_st4_x86_64, dwarf_st5_x86_64, dwarf_st6_x86_64, dwarf_st7_x86_64, // MMX Registers dwarf_mm0_x86_64 = 41, dwarf_mm1_x86_64, dwarf_mm2_x86_64, dwarf_mm3_x86_64, dwarf_mm4_x86_64, dwarf_mm5_x86_64, dwarf_mm6_x86_64, dwarf_mm7_x86_64, // Control and Status Flags Register dwarf_rflags_x86_64 = 49, // selector registers dwarf_es_x86_64 = 50, dwarf_cs_x86_64, dwarf_ss_x86_64, dwarf_ds_x86_64, dwarf_fs_x86_64, dwarf_gs_x86_64, // Floating point control registers dwarf_mxcsr_x86_64 = 64, // Media Control and Status dwarf_fctrl_x86_64, // x87 control word dwarf_fstat_x86_64, // x87 status word // Upper Vector Registers dwarf_ymm0h_x86_64 = 67, dwarf_ymm1h_x86_64, dwarf_ymm2h_x86_64, dwarf_ymm3h_x86_64, dwarf_ymm4h_x86_64, dwarf_ymm5h_x86_64, dwarf_ymm6h_x86_64, dwarf_ymm7h_x86_64, dwarf_ymm8h_x86_64, dwarf_ymm9h_x86_64, dwarf_ymm10h_x86_64, dwarf_ymm11h_x86_64, dwarf_ymm12h_x86_64, dwarf_ymm13h_x86_64, dwarf_ymm14h_x86_64, dwarf_ymm15h_x86_64, // MPX registers dwarf_bnd0_x86_64 = 126, dwarf_bnd1_x86_64, dwarf_bnd2_x86_64, dwarf_bnd3_x86_64, // AVX2 Vector Mask Registers // dwarf_k0_x86_64 = 118, // dwarf_k1_x86_64, // dwarf_k2_x86_64, // dwarf_k3_x86_64, // dwarf_k4_x86_64, // dwarf_k5_x86_64, // dwarf_k6_x86_64, // dwarf_k7_x86_64, }; //--------------------------------------------------------------------------- // Generic floating-point registers //--------------------------------------------------------------------------- struct MMSReg { uint8_t bytes[10]; uint8_t pad[6]; }; struct XMMReg { uint8_t bytes[16]; // 128-bits for each XMM register }; // i387_fxsave_struct struct FXSAVE { uint16_t fctrl; // FPU Control Word (fcw) uint16_t fstat; // FPU Status Word (fsw) - uint8_t ftag; // FPU Tag Word (ftw) - uint8_t reserved_1; // Reserved + uint16_t ftag; // FPU Tag Word (ftw) uint16_t fop; // Last Instruction Opcode (fop) union { struct { uint64_t fip; // Instruction Pointer uint64_t fdp; // Data Pointer } x86_64; struct { uint32_t fioff; // FPU IP Offset (fip) uint32_t fiseg; // FPU IP Selector (fcs) uint32_t fooff; // FPU Operand Pointer Offset (foo) uint32_t foseg; // FPU Operand Pointer Selector (fos) } i386_; // Added _ in the end to avoid error with gcc defining i386 in some // cases } ptr; uint32_t mxcsr; // MXCSR Register State uint32_t mxcsrmask; // MXCSR Mask MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes XMMReg xmm[16]; // 16*16 bytes for each XMM-reg = 256 bytes uint8_t padding1[48]; uint64_t xcr0; uint8_t padding2[40]; }; //--------------------------------------------------------------------------- // Extended floating-point registers //--------------------------------------------------------------------------- struct YMMHReg { uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register }; struct YMMReg { uint8_t bytes[32]; // 16 * 16 bits for each YMM register }; struct YMM { YMMReg ymm[16]; // assembled from ymmh and xmm registers }; struct MPXReg { uint8_t bytes[16]; // MPX 128 bit bound registers }; struct MPXCsr { uint8_t bytes[8]; // MPX 64 bit bndcfgu and bndstatus registers (collectively // BNDCSR state) }; struct MPX { MPXReg mpxr[4]; MPXCsr mpxc[2]; }; LLVM_PACKED_START struct XSAVE_HDR { uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states // supported by the processor uint64_t xcomp_bv; // Mask to indicate the format of the XSAVE area and of // the XRSTOR instruction uint64_t reserved1[1]; uint64_t reserved2[5]; }; LLVM_PACKED_END // x86 extensions to FXSAVE (i.e. for AVX and MPX processors) LLVM_PACKED_START struct LLVM_ALIGNAS(64) XSAVE { FXSAVE i387; // floating point registers typical in i387_fxsave_struct XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the // following extensions are usable YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes // are in FXSAVE.xmm for compatibility with SSE) uint64_t reserved3[16]; MPXReg mpxr[4]; // MPX BNDREG state, containing 128-bit bound registers MPXCsr mpxc[2]; // MPX BNDCSR state, containing 64-bit BNDCFGU and // BNDSTATUS registers }; LLVM_PACKED_END // Floating-point registers struct FPR { // Thread state for the floating-point unit of the processor read by ptrace. union XSTATE { FXSAVE fxsave; // Generic floating-point registers. XSAVE xsave; // x86 extended processor state. } xstate; }; //--------------------------------------------------------------------------- // ptrace PTRACE_GETREGSET, PTRACE_SETREGSET structure //--------------------------------------------------------------------------- struct IOVEC { void *iov_base; // pointer to XSAVE size_t iov_len; // sizeof(XSAVE) }; #endif diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index c7c3140b121a..f7b611802fbf 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -1,77 +1,83 @@ add_custom_target(LLDBUnitTests) set_target_properties(LLDBUnitTests PROPERTIES FOLDER "LLDB tests") include_directories(${LLDB_SOURCE_ROOT}) include_directories(${LLDB_PROJECT_ROOT}) set(LLDB_GTEST_COMMON_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/gtest_common.h) if (MSVC) list(APPEND LLVM_COMPILE_FLAGS /FI ${LLDB_GTEST_COMMON_INCLUDE}) else () list(APPEND LLVM_COMPILE_FLAGS -include ${LLDB_GTEST_COMMON_INCLUDE}) endif () include(${LLDB_PROJECT_ROOT}/cmake/LLDBDependencies.cmake) if (LLDB_BUILT_STANDALONE) # Build the gtest library needed for unittests, if we have LLVM sources # handy. if (EXISTS ${LLVM_MAIN_SRC_DIR}/utils/unittest AND NOT TARGET gtest) add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/unittest utils/unittest) endif() + # LLVMTestingSupport library is needed for Process/gdb-remote. + if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Testing/Support + AND NOT TARGET LLVMTestingSupport) + add_subdirectory(${LLVM_MAIN_SRC_DIR}/lib/Testing/Support + lib/Testing/Support) + endif() endif() function(add_lldb_unittest test_name) cmake_parse_arguments(ARG "" "" "LINK_LIBS;LINK_COMPONENTS" ${ARGN}) list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS}) add_unittest(LLDBUnitTests ${test_name} ${ARG_UNPARSED_ARGUMENTS} ) add_custom_command( TARGET ${test_name} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/Inputs) target_link_libraries(${test_name} ${ARG_LINK_LIBS} ${LLDB_SYSTEM_LIBS}) endfunction() function(add_unittest_inputs test_name inputs) foreach (INPUT ${inputs}) add_custom_command( TARGET ${test_name} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Inputs/${INPUT} ${CMAKE_CURRENT_BINARY_DIR}/Inputs COMMENT "Copying ${INPUT} to binary directory.") endforeach() endfunction() add_subdirectory(Breakpoint) add_subdirectory(Core) add_subdirectory(Editline) add_subdirectory(Expression) add_subdirectory(Host) add_subdirectory(Interpreter) add_subdirectory(Language) add_subdirectory(ObjectFile) add_subdirectory(Platform) add_subdirectory(Process) add_subdirectory(ScriptInterpreter) add_subdirectory(Signals) add_subdirectory(Symbol) add_subdirectory(SymbolFile) add_subdirectory(Target) add_subdirectory(tools) add_subdirectory(UnwindAssembly) add_subdirectory(Utility) if(LLDB_CAN_USE_DEBUGSERVER) add_subdirectory(debugserver) endif()