diff options
| author | Greg Clayton <gclayton@apple.com> | 2011-08-01 17:08:02 +0000 |
|---|---|---|
| committer | Greg Clayton <gclayton@apple.com> | 2011-08-01 17:08:02 +0000 |
| commit | 89f138ae636432b3e7608b341437d27a49b4bdc4 (patch) | |
| tree | 1ab653578407dce02f6306bdeab606e12419da56 | |
| parent | 0516c503ec787363933052edb7e6c2931438cc61 (diff) | |
| download | bcm5719-llvm-89f138ae636432b3e7608b341437d27a49b4bdc4.tar.gz bcm5719-llvm-89f138ae636432b3e7608b341437d27a49b4bdc4.zip | |
Remove the deprecated MacOSX native plug-in.
llvm-svn: 136626
37 files changed, 38 insertions, 11384 deletions
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 43d11ddbecd..394d6e85e28 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -74,7 +74,6 @@ 2671A0D013482601003A87BB /* ConnectionMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2671A0CF13482601003A87BB /* ConnectionMachPort.cpp */; }; 26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */; }; 26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */; }; - 2676045A13D49D2300AB1B6A /* ProcessControl-mig.defs in Sources */ = {isa = PBXBuildFile; fileRef = 260C89A110F57C5600BB2B04 /* ProcessControl-mig.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; 267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */; }; 267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */; }; 2686536C1370ACB200D186A3 /* OptionGroupBoolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536B1370ACB200D186A3 /* OptionGroupBoolean.cpp */; }; @@ -220,19 +219,6 @@ 2689009F13353E4200698AC0 /* ProcessGDBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618EE5F1315B29C001D6D71 /* ProcessGDBRemote.cpp */; }; 268900A013353E4200698AC0 /* ProcessGDBRemoteLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618EE611315B29C001D6D71 /* ProcessGDBRemoteLog.cpp */; }; 268900A113353E4200698AC0 /* ThreadGDBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2618EE631315B29C001D6D71 /* ThreadGDBRemote.cpp */; }; - 268900A213353E5000698AC0 /* MachException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C899210F57C5600BB2B04 /* MachException.cpp */; }; - 268900A313353E5000698AC0 /* MachTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C899410F57C5600BB2B04 /* MachTask.cpp */; }; - 268900A413353E5000698AC0 /* MachThreadContext_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C899710F57C5600BB2B04 /* MachThreadContext_arm.cpp */; }; - 268900A513353E5000698AC0 /* MachThreadContext_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C899910F57C5600BB2B04 /* MachThreadContext_i386.cpp */; }; - 268900A613353E5000698AC0 /* MachThreadContext_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C899B10F57C5600BB2B04 /* MachThreadContext_x86_64.cpp */; }; - 268900A713353E5000698AC0 /* MachVMMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C899D10F57C5600BB2B04 /* MachVMMemory.cpp */; }; - 268900A813353E5000698AC0 /* MachVMRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C899F10F57C5600BB2B04 /* MachVMRegion.cpp */; }; - 268900A913353E5000698AC0 /* ProcessMacOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C89A310F57C5600BB2B04 /* ProcessMacOSX.cpp */; }; - 268900AA13353E5000698AC0 /* ProcessMacOSXLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C89A510F57C5600BB2B04 /* ProcessMacOSXLog.cpp */; }; - 268900AB13353E5000698AC0 /* RegisterContextMach_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C89A910F57C5600BB2B04 /* RegisterContextMach_arm.cpp */; }; - 268900AC13353E5000698AC0 /* RegisterContextMach_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C89AB10F57C5600BB2B04 /* RegisterContextMach_i386.cpp */; }; - 268900AD13353E5000698AC0 /* RegisterContextMach_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C89AD10F57C5600BB2B04 /* RegisterContextMach_x86_64.cpp */; }; - 268900AE13353E5000698AC0 /* ThreadMacOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C89AF10F57C5600BB2B04 /* ThreadMacOSX.cpp */; }; 268900AF13353E5000698AC0 /* UnwindLLDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF68D32F1255A110002FF25B /* UnwindLLDB.cpp */; }; 268900B013353E5000698AC0 /* RegisterContextLLDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF68D2541255416E002FF25B /* RegisterContextLLDB.cpp */; }; 268900B413353E5000698AC0 /* RegisterContextMacOSXFrameBackchain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E3EEF711A994E800FBADB6 /* RegisterContextMacOSXFrameBackchain.cpp */; }; @@ -539,37 +525,6 @@ 260C898610F57C5600BB2B04 /* ObjectFileELF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectFileELF.h; sourceTree = "<group>"; }; 260C898810F57C5600BB2B04 /* ObjectFileMachO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectFileMachO.cpp; sourceTree = "<group>"; }; 260C898910F57C5600BB2B04 /* ObjectFileMachO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectFileMachO.h; sourceTree = "<group>"; }; - 260C898D10F57C5600BB2B04 /* cc-swig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = "cc-swig"; sourceTree = "<group>"; }; - 260C898E10F57C5600BB2B04 /* config.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = config.pl; sourceTree = "<group>"; }; - 260C898F10F57C5600BB2B04 /* test-ProcessDebug.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; path = "test-ProcessDebug.pl"; sourceTree = "<group>"; }; - 260C899210F57C5600BB2B04 /* MachException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachException.cpp; sourceTree = "<group>"; }; - 260C899310F57C5600BB2B04 /* MachException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachException.h; sourceTree = "<group>"; }; - 260C899410F57C5600BB2B04 /* MachTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachTask.cpp; sourceTree = "<group>"; }; - 260C899510F57C5600BB2B04 /* MachTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachTask.h; sourceTree = "<group>"; }; - 260C899610F57C5600BB2B04 /* MachThreadContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachThreadContext.h; sourceTree = "<group>"; }; - 260C899710F57C5600BB2B04 /* MachThreadContext_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachThreadContext_arm.cpp; sourceTree = "<group>"; }; - 260C899810F57C5600BB2B04 /* MachThreadContext_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachThreadContext_arm.h; sourceTree = "<group>"; }; - 260C899910F57C5600BB2B04 /* MachThreadContext_i386.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachThreadContext_i386.cpp; sourceTree = "<group>"; }; - 260C899A10F57C5600BB2B04 /* MachThreadContext_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachThreadContext_i386.h; sourceTree = "<group>"; }; - 260C899B10F57C5600BB2B04 /* MachThreadContext_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachThreadContext_x86_64.cpp; sourceTree = "<group>"; }; - 260C899C10F57C5600BB2B04 /* MachThreadContext_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachThreadContext_x86_64.h; sourceTree = "<group>"; }; - 260C899D10F57C5600BB2B04 /* MachVMMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachVMMemory.cpp; sourceTree = "<group>"; }; - 260C899E10F57C5600BB2B04 /* MachVMMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachVMMemory.h; sourceTree = "<group>"; }; - 260C899F10F57C5600BB2B04 /* MachVMRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachVMRegion.cpp; sourceTree = "<group>"; }; - 260C89A010F57C5600BB2B04 /* MachVMRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachVMRegion.h; sourceTree = "<group>"; }; - 260C89A110F57C5600BB2B04 /* ProcessControl-mig.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = "ProcessControl-mig.defs"; sourceTree = "<group>"; }; - 260C89A310F57C5600BB2B04 /* ProcessMacOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessMacOSX.cpp; sourceTree = "<group>"; }; - 260C89A410F57C5600BB2B04 /* ProcessMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessMacOSX.h; sourceTree = "<group>"; }; - 260C89A510F57C5600BB2B04 /* ProcessMacOSXLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessMacOSXLog.cpp; sourceTree = "<group>"; }; - 260C89A610F57C5600BB2B04 /* ProcessMacOSXLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessMacOSXLog.h; sourceTree = "<group>"; }; - 260C89A910F57C5600BB2B04 /* RegisterContextMach_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMach_arm.cpp; sourceTree = "<group>"; }; - 260C89AA10F57C5600BB2B04 /* RegisterContextMach_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextMach_arm.h; sourceTree = "<group>"; }; - 260C89AB10F57C5600BB2B04 /* RegisterContextMach_i386.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMach_i386.cpp; sourceTree = "<group>"; }; - 260C89AC10F57C5600BB2B04 /* RegisterContextMach_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextMach_i386.h; sourceTree = "<group>"; }; - 260C89AD10F57C5600BB2B04 /* RegisterContextMach_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMach_x86_64.cpp; sourceTree = "<group>"; }; - 260C89AE10F57C5600BB2B04 /* RegisterContextMach_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextMach_x86_64.h; sourceTree = "<group>"; }; - 260C89AF10F57C5600BB2B04 /* ThreadMacOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadMacOSX.cpp; sourceTree = "<group>"; }; - 260C89B010F57C5600BB2B04 /* ThreadMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadMacOSX.h; sourceTree = "<group>"; }; 260C89B310F57C5600BB2B04 /* DWARFAbbreviationDeclaration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DWARFAbbreviationDeclaration.cpp; sourceTree = "<group>"; }; 260C89B410F57C5600BB2B04 /* DWARFAbbreviationDeclaration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWARFAbbreviationDeclaration.h; sourceTree = "<group>"; }; 260C89B610F57C5600BB2B04 /* DWARFAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWARFAttribute.h; sourceTree = "<group>"; }; @@ -1525,74 +1480,11 @@ children = ( 4CEE62F71145F1C70064CF93 /* GDB Remote */, 2642FBA713D003B400ED6808 /* MacOSX-Kernel */, - 260C898B10F57C5600BB2B04 /* MacOSX-User */, 26B4666E11A2080F00CF6220 /* Utility */, ); path = Process; sourceTree = "<group>"; }; - 260C898B10F57C5600BB2B04 /* MacOSX-User */ = { - isa = PBXGroup; - children = ( - 260C898C10F57C5600BB2B04 /* scripts */, - 260C899010F57C5600BB2B04 /* source */, - ); - path = "MacOSX-User"; - sourceTree = "<group>"; - }; - 260C898C10F57C5600BB2B04 /* scripts */ = { - isa = PBXGroup; - children = ( - 260C898D10F57C5600BB2B04 /* cc-swig */, - 260C898E10F57C5600BB2B04 /* config.pl */, - 260C898F10F57C5600BB2B04 /* test-ProcessDebug.pl */, - ); - path = scripts; - sourceTree = "<group>"; - }; - 260C899010F57C5600BB2B04 /* source */ = { - isa = PBXGroup; - children = ( - 260C899110F57C5600BB2B04 /* MacOSX */, - 260C89A310F57C5600BB2B04 /* ProcessMacOSX.cpp */, - 260C89A410F57C5600BB2B04 /* ProcessMacOSX.h */, - 260C89A510F57C5600BB2B04 /* ProcessMacOSXLog.cpp */, - 260C89A610F57C5600BB2B04 /* ProcessMacOSXLog.h */, - 260C89A910F57C5600BB2B04 /* RegisterContextMach_arm.cpp */, - 260C89AA10F57C5600BB2B04 /* RegisterContextMach_arm.h */, - 260C89AB10F57C5600BB2B04 /* RegisterContextMach_i386.cpp */, - 260C89AC10F57C5600BB2B04 /* RegisterContextMach_i386.h */, - 260C89AD10F57C5600BB2B04 /* RegisterContextMach_x86_64.cpp */, - 260C89AE10F57C5600BB2B04 /* RegisterContextMach_x86_64.h */, - 260C89AF10F57C5600BB2B04 /* ThreadMacOSX.cpp */, - 260C89B010F57C5600BB2B04 /* ThreadMacOSX.h */, - ); - path = source; - sourceTree = "<group>"; - }; - 260C899110F57C5600BB2B04 /* MacOSX */ = { - isa = PBXGroup; - children = ( - 260C899210F57C5600BB2B04 /* MachException.cpp */, - 260C899310F57C5600BB2B04 /* MachException.h */, - 260C899410F57C5600BB2B04 /* MachTask.cpp */, - 260C899510F57C5600BB2B04 /* MachTask.h */, - 260C899610F57C5600BB2B04 /* MachThreadContext.h */, - 260C899710F57C5600BB2B04 /* MachThreadContext_arm.cpp */, - 260C899810F57C5600BB2B04 /* MachThreadContext_arm.h */, - 260C899910F57C5600BB2B04 /* MachThreadContext_i386.cpp */, - 260C899A10F57C5600BB2B04 /* MachThreadContext_i386.h */, - 260C899B10F57C5600BB2B04 /* MachThreadContext_x86_64.cpp */, - 260C899C10F57C5600BB2B04 /* MachThreadContext_x86_64.h */, - 260C899D10F57C5600BB2B04 /* MachVMMemory.cpp */, - 260C899E10F57C5600BB2B04 /* MachVMMemory.h */, - 260C899F10F57C5600BB2B04 /* MachVMRegion.cpp */, - 260C89A010F57C5600BB2B04 /* MachVMRegion.h */, - 260C89A110F57C5600BB2B04 /* ProcessControl-mig.defs */, - ); - path = MacOSX; - sourceTree = "<group>"; - }; 260C89B110F57C5600BB2B04 /* SymbolFile */ = { isa = PBXGroup; children = ( @@ -3197,19 +3089,6 @@ 2689009F13353E4200698AC0 /* ProcessGDBRemote.cpp in Sources */, 268900A013353E4200698AC0 /* ProcessGDBRemoteLog.cpp in Sources */, 268900A113353E4200698AC0 /* ThreadGDBRemote.cpp in Sources */, - 268900A213353E5000698AC0 /* MachException.cpp in Sources */, - 268900A313353E5000698AC0 /* MachTask.cpp in Sources */, - 268900A413353E5000698AC0 /* MachThreadContext_arm.cpp in Sources */, - 268900A513353E5000698AC0 /* MachThreadContext_i386.cpp in Sources */, - 268900A613353E5000698AC0 /* MachThreadContext_x86_64.cpp in Sources */, - 268900A713353E5000698AC0 /* MachVMMemory.cpp in Sources */, - 268900A813353E5000698AC0 /* MachVMRegion.cpp in Sources */, - 268900A913353E5000698AC0 /* ProcessMacOSX.cpp in Sources */, - 268900AA13353E5000698AC0 /* ProcessMacOSXLog.cpp in Sources */, - 268900AB13353E5000698AC0 /* RegisterContextMach_arm.cpp in Sources */, - 268900AC13353E5000698AC0 /* RegisterContextMach_i386.cpp in Sources */, - 268900AD13353E5000698AC0 /* RegisterContextMach_x86_64.cpp in Sources */, - 268900AE13353E5000698AC0 /* ThreadMacOSX.cpp in Sources */, 268900AF13353E5000698AC0 /* UnwindLLDB.cpp in Sources */, 268900B013353E5000698AC0 /* RegisterContextLLDB.cpp in Sources */, 268900B413353E5000698AC0 /* RegisterContextMacOSXFrameBackchain.cpp in Sources */, @@ -3365,7 +3244,6 @@ 265205AA13D3E3F700132FE2 /* RegisterContextKDP_i386.cpp in Sources */, 265205AC13D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp in Sources */, 2628A4D513D4977900F5487A /* ThreadKDP.cpp in Sources */, - 2676045A13D49D2300AB1B6A /* ProcessControl-mig.defs in Sources */, 26D7E45D13D5E30A007FD12B /* SocketAddress.cpp in Sources */, B271B11413D6139300C3FEDB /* FormatClasses.cpp in Sources */, 94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */, diff --git a/lldb/source/Plugins/Process/MacOSX-User/Makefile b/lldb/source/Plugins/Process/MacOSX-User/Makefile deleted file mode 100644 index 8fb3e46e6c8..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- source/Plugins/Process/MacOSX-User/Makefile ---------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginProcessMacOSXUser -BUILD_ARCHIVE = 1 - -Source := $(wildcard $(PROJ_SRC_DIR)/source/*.cpp) -Source += $(wildcard $(PROJ_SRC_DIR)/source/MacOSX/*.cpp) - -include $(LLDB_LEVEL)/Makefile diff --git a/lldb/source/Plugins/Process/MacOSX-User/scripts/cc-swig b/lldb/source/Plugins/Process/MacOSX-User/scripts/cc-swig deleted file mode 100644 index 0bb089a653e..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/scripts/cc-swig +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/perl - -use File::Basename; - -sub execute_command -{ - print join(' ', @_), "\n"; - if (scalar(@_) > 0) { - system(@_); - } else { - system($_[0]); - } -} - -my $infile = $ENV{SCRIPT_INPUT_FILE_1}; -my($in_basename, $in_dirname, $in_extension) = fileparse($infile, qr/\.[^.]*/); -my $outdir = "$ENV{DERIVED_FILE_DIR}"; -my $perl_wrap_c = "$outdir/${in_basename}_perl_wrap.c"; -mkdir "$ENV{OBJECT_FILE_DIR}"; -my $perl_wrap_o = "$ENV{OBJECT_FILE_DIR}/${in_basename}_perl_wrap.o"; -my $perl_module = "$outdir/${in_basename}.pm"; -my $header_paths = "-I'../../../../../debugcore/source' -I'../../../../../DebugBase'"; -my $framework_opts = "-F'$ENV{CONFIGURATION_BUILD_DIR}' "; -execute_command("/usr/bin/swig -shadow -perl5 -DHAS_BOOL $header_paths -outdir '$outdir' -o '$perl_wrap_c' '$infile'"); - -# Get any needed perl options for the next compile -my $ccopts = `perl -MExtUtils::Embed -e ccopts`; -my $libperl_dir = undef; -if ($ccopts =~ /-I(\/System.*CORE)/) -{ - $libperl_dir = $1; - print "libperl directory: '$libperl_dir'\n"; -} - -execute_command("cd '$ENV{OBJECT_FILE_DIR}' && ln -s '$libperl_dir/libperl.dylib'"); - - -# Strip out the default architectures it gave us, we will add them back with -# the $arch_opts below -$ccopts =~ s/-arch [a-z_0-9]+//g; - -# Get a list of our build architectures -my $arch_opts = "-arch " . join(' -arch ', split('\s+', $ENV{ARCHS})); - -execute_command("gcc -c -Dbool=char $arch_opts $ccopts $header_paths $framework_opts -I'$ENV{PROJECT_DIR}/source' '$perl_wrap_c' -o '$perl_wrap_o'"); - -execute_command("cp '$perl_module' '$ENV{CONFIGURATION_BUILD_DIR}/$ENV{SHARED_SUPPORT_FOLDER_PATH}'");
\ No newline at end of file diff --git a/lldb/source/Plugins/Process/MacOSX-User/scripts/config.pl b/lldb/source/Plugins/Process/MacOSX-User/scripts/config.pl deleted file mode 100644 index a6cf6ce2396..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/scripts/config.pl +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/perl - -use strict; -my $config_file = "$ENV{SCRIPT_OUTPUT_FILE_0}"; - -# Define the tests we need to run during this configuration -my @config_tests = ( - { - NAME => "HAVE_64_BIT_MACH_EXCEPTIONS", - TEST => "-e '$ENV{SDKROOT}/usr/include/mach/mach_exc.defs'", - COMMENT => "// Defined if we can use 64 bit mach exceptions", - FAIL => "#undef HAVE_64_BIT_MACH_EXCEPTIONS\ -#define mach_exception_data_t exception_data_t\ -#define mach_exception_data_type_t exception_data_type_t\ -#define mach_exc_server exc_server\ -#define MACH_EXCEPTION_CODES 0\n", - SUCCESS => "#define HAVE_64_BIT_MACH_EXCEPTIONS 1\n", - } -); - -#---------------------------------------------------------------------- -# Open the config file -#---------------------------------------------------------------------- -open(CONFIG, "> $config_file") || die "Couldn't open '$config_file' for writing: $!\n"; -print CONFIG "/*" . "-" x 72 . "\n"; -print CONFIG "// This file is auto generated by a config.pl, do not edit by hand!\n"; -print CONFIG "//" . "-" x 72 . "\n"; -print CONFIG "// COMMAND LINE\n"; -print CONFIG "// " . join(' ', @ARGV) . "\n"; -print CONFIG "//" . "-" x 72 . "\n"; -print CONFIG "// ENVIRONMENT\n"; -my $key; -my $val; -while (($key, $val) = each %ENV) -{ - printf CONFIG "// %s = %s\n", $key, $val; -} -print CONFIG "//" . "-" x 72 . "\n"; -print CONFIG "// SETTINGS\n"; -print CONFIG "// config_file: '$config_file'\n"; -print CONFIG "//" . "-" x 72 . "\n"; -print CONFIG "*/\n\n"; -print CONFIG "#ifndef liblldb_PDConfig_h_\n"; -print CONFIG "#define liblldb_PDConfig_h_\n"; - - -#---------------------------------------------------------------------- -# Run the tests -#---------------------------------------------------------------------- -foreach my $test_href (@config_tests) -{ - if (exists $test_href->{COMMENT}) { - print CONFIG "\n$test_href->{COMMENT}\n"; - } else { - print CONFIG "\n// $test_href->{NAME}\n"; - } - - my $test_result = eval "$test_href->{TEST}"; - if ($test_result != 0) - { - print CONFIG "$test_href->{SUCCESS}\n"; - } - else - { - print CONFIG "$test_href->{FAIL}\n"; - } -} - -print CONFIG "#endif // #ifndef liblldb_PDConfig_h_\n"; -close(CONFIG); - diff --git a/lldb/source/Plugins/Process/MacOSX-User/scripts/test-ProcessDebug.pl b/lldb/source/Plugins/Process/MacOSX-User/scripts/test-ProcessDebug.pl deleted file mode 100755 index e7feb51197a..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/scripts/test-ProcessDebug.pl +++ /dev/null @@ -1,409 +0,0 @@ -#!/usr/bin/perl - -use strict; -use Cwd 'abs_path'; -our $home = $ENV{HOME} || die "ERROR: Couldn't deduce your home directory...\n"; - -our @inc_paths = ( - './include', -); - -my $inc_paths_added = 0; -foreach my $inc_path (@inc_paths) -{ - if (-e $inc_path) - { - push (@INC, abs_path($inc_path)); - $inc_paths_added++; - } -} - -if ($inc_paths_added == 0) -{ - die "Please compile the Release version of lldb\n"; -} - -require lldb; - -# my $state = lldb::eStateAttaching; - -use constant UINT32_MAX => 4294967295; - -#---------------------------------------------------------------------- -# Interactive Commands -#---------------------------------------------------------------------- -our %commands = ( - break => { - name => 'break', # in case an alias is used to get to this command - description => "Sets a breakpoint.", - usage => ["break ADDR"], - function => \&command_set_breakpoint, - runs_target => 0, - }, - delete => { - name => 'delete', # in case an alias is used to get to this command - description => "Deletes one or more breakpoints by ID.\ -If no breakpoint IDs are given all breakpoints will be deleted.\ -If one or more IDs are given, only those breakpoints will be deleted.", - usage => ["delete [ID1 ID2 ...]"], - function => \&command_clear_breakpoint, - runs_target => 0, - }, - continue => { - name => 'continue', # in case an alias is used to get to this command - description => "Continues target execution.", - usage => ["continue [ADDR]"], - function => \&command_continue, - runs_target => 1 - }, - step => { - name => 'step', # in case an alias is used to get to this command - description => "Single steps one instruction.", - usage => ["step"], - function => \&command_step, - runs_target => 1 - }, - info => { - name => 'info', # in case an alias is used to get to this command - description => "Gets info on a variety of things.", - usage => ["info reg", "info thread", "info threads"], - function => \&command_info, - runs_target => 0 - }, - help => { - name => 'help', # in case an alias is used to get to this command - description => "Displays a list of all commands, or help for a specific command.", - usage => ["help", "help CMD"], - function => \&command_help, - runs_target => 0 - } -); - -#---------------------------------------------------------------------- -# Command aliases -#---------------------------------------------------------------------- -our %aliases = ( - b => $commands{break}, - c => $commands{continue}, - s => $commands{step}, - d => $commands{delete}, - h => $commands{help} -); - -our $opt_g = 0; # Enable verbose debug logging -our $opt_v = 0; # Verbose mode -my $prev_command_href = undef; -my $stdio = '/dev/stdin'; -my $launch = 0; -my @env = (); -my @break_ids; - -#---------------------------------------------------------------------- -# Given a command string, return the command hash reference for it, or -# undef if it doesn't exist. -#---------------------------------------------------------------------- -sub get_command_hash_ref -{ - my $cmd = shift; - my $cmd_href = undef; - if (length($cmd) == 0) { $cmd_href = $prev_command_href; } - elsif (exists $aliases{$cmd}) { $cmd_href = $aliases{$cmd}; } - elsif (exists $commands{$cmd}) { $cmd_href = $commands{$cmd}; } - defined $cmd_href and $prev_command_href = $cmd_href; - return $cmd_href; -} - -#---------------------------------------------------------------------- -# Set a breakpoint -#---------------------------------------------------------------------- -sub command_set_breakpoint -{ - my $pid = shift; - my $tid = shift; - $opt_g and print "command_set_breakpoint (pid = $pid, locations = @_)\n"; - foreach my $location (@_) - { - my $success = 0; - my $address = hex($location); - if ($address != 0) - { - my $break_id = lldb::PDBreakpointSet ($pid, $address, 1, 0); - if ($break_id != $lldb::PD_INVALID_BREAK_ID) - { - printf("Breakpoint %i is set.\n", $break_id); - push(@break_ids, $break_id); - $success = 1; - } - } - $success or print("error: failed to set breakpoint at $location.\n"); - } - return 1; -} - -#---------------------------------------------------------------------- -# Clear a breakpoint -#---------------------------------------------------------------------- -sub command_clear_breakpoint -{ - my $pid = shift; - my $tid = shift; - if (@_) - { - my $break_id; - my @cleared_break_ids; - my @new_break_ids; - $opt_g and print "command_clear_breakpoint (pid = $pid, break_ids = @_)\n"; - foreach $break_id (@_) - { - if (lldb::PDBreakpointClear ($pid, $break_id)) - { - printf("Breakpoint %i has been cleared.\n", $break_id); - push (@cleared_break_ids, $break_id); - } - else - { - printf("error: failed to clear breakpoint %i.\n", $break_id); - } - } - - foreach my $old_break_id (@break_ids) - { - my $found_break_id = 0; - foreach $break_id (@cleared_break_ids) - { - if ($old_break_id == $break_id) - { - $found_break_id = 1; - } - } - $found_break_id or push (@new_break_ids, $old_break_id); - } - @break_ids = @new_break_ids; - } - else - { - # Nothing specified, clear all breakpoints - return command_clear_breakpoint($pid, $tid, @break_ids); - } - return 1; -} -#---------------------------------------------------------------------- -# Continue program execution -#---------------------------------------------------------------------- -sub command_continue -{ - my $pid = shift; - my $tid = shift; - $opt_g and print "command_continue (pid = $pid)\n"; - if ($pid != $lldb::PD_INVALID_PROCESS_ID) - { - $opt_v and printf("Resuming pid %d...\n", $pid); - return lldb::PDProcessResume ($pid); - } - return 0; -} - -sub command_step -{ - my $pid = shift; - my $tid = shift; - $opt_g and print "command_step (pid = $pid, tid = $tid)\n"; - if ($pid != $lldb::PD_INVALID_PROCESS_ID) - { - $opt_v and printf("Single stepping pid %d tid = %4.4x...\n", $pid, $tid); - return lldb::PDThreadResume ($pid, $tid, 1); - } - return 0; -} - -sub command_info -{ - my $pid = shift; - my $tid = shift; - $opt_g and print "command_step (pid = $pid, tid = $tid)\n"; - if ($pid != $lldb::PD_INVALID_PROCESS_ID) - { - if (@_) - { - my $info_cmd = shift; - if ($info_cmd eq 'reg') - { - - } - elsif ($info_cmd eq 'thread') - { - # info on the current thread - printf("thread 0x%4.4x %s\n", $tid, lldb::PDThreadGetInfo($pid, $tid)); - } - elsif ($info_cmd eq 'threads') - { - my $num_threads = lldb::PDProcessGetNumThreads( $pid ); - for my $thread_num (1..$num_threads) - { - my $curr_tid = lldb::PDProcessGetThreadAtIndex ( $pid, $thread_num - 1 ); - printf("%c%u - thread 0x%4.4x %s\n", $curr_tid == $tid ? '*' : ' ', $thread_num, $curr_tid, lldb::PDThreadGetInfo($pid, $curr_tid)); - } - } - } - } - return 1; -} -#---------------------------------------------------------------------- -# Get help on all commands, or a specific list of commands -#---------------------------------------------------------------------- -sub command_help -{ - my $pid = shift; - my $tid = shift; - if (@_) - { - $opt_g and print "command_continue (pid = $pid, commands = @_)\n"; - foreach my $cmd (@_) - { - my $cmd_href = get_command_hash_ref($cmd); - if ($cmd_href) - { - print '#', '-' x 72, "\n# $cmd_href->{name}\n", '#', '-' x 72, "\n"; - my $usage_aref = $cmd_href->{usage}; - if (@{$usage_aref}) - { - print " USAGE\n"; - foreach my $usage (@{$usage_aref}) { - print " $usage\n"; - } - print "\n"; - } - print " DESCRIPTION\n $cmd_href->{description}\n\n"; - } - else - { - print " invalid command: '$cmd'\n\n"; - } - } - } - else - { - return command_help($pid, sort keys %commands); - } - return 1; -} - - -#lldb::PDLogSetLogMask ($lldb::PD_LOG_ALL); -#lldb::PDLogSetLogFile ('/dev/stdout'); - -print "running: ", join(' ', @ARGV), "\n"; - -my $pid = lldb::PDProcessLaunch ($ARGV[0], \@ARGV, \@env, "i386", '/dev/stdin', '/dev/stdout', '/dev/stderr', $launch, '', 0); -my $pid_state; -while ($pid) -{ - $opt_g and printf("PDProcessWaitForEvents (%d, 0x%4.4x, SET, 1)\n", $pid, $lldb::PD_ALL_EVENTS); - my $events = lldb::PDProcessWaitForEvents ($pid, $lldb::PD_ALL_EVENTS, 1, 1); - if ($events) - { - $opt_g and printf ("Got event: 0x%8.8x\n", $events); - - if ($events & $lldb::PD_EVENT_IMAGES_CHANGED) - { - $opt_g and printf("pid %d images changed...\n", $pid); - } - - if ($events & $lldb::PD_EVENT_STDIO) - { - $opt_g and printf("pid %d has stdio...\n", $pid); - } - - if ($events & $lldb::PD_EVENT_ASYNC_INTERRUPT) - { - $opt_g and printf("pid %d got async interrupt...\n", $pid); - } - - if ($events & $lldb::PD_EVENT_RUNNING) - { - $pid_state = lldb::PDProcessGetState ($pid); - $opt_v and printf( "pid %d state: %s.\n", $pid, lldb::PDStateAsString ($pid_state) ); - } - - if ($events & $lldb::PD_EVENT_STOPPED) - { - $pid_state = lldb::PDProcessGetState ($pid); - $opt_v and printf( "pid %d state: %s.\n", $pid, lldb::PDStateAsString ($pid_state) ); - - if ($pid_state == $lldb::eStateUnloaded || - $pid_state == $lldb::eStateAttaching || - $pid_state == $lldb::eStateLaunching ) - { - - } - elsif ( $pid_state == $lldb::eStateStopped ) - { - my $tid = lldb::PDProcessGetSelectedThread ( $pid ); - my $pc = lldb::PDThreadGetRegisterHexValueByName($pid, $tid, $lldb::PD_REGISTER_SET_ALL, "eip", 0); - $pc != 0 and printf("pc = 0x%8.8x ", $pc); - # my $sp = lldb::PDThreadGetRegisterHexValueByName($pid, $tid, $lldb::PD_REGISTER_SET_ALL, "esp", 0); - # $sp != 0 and printf("sp = 0x%8.8x ", $sp); - # my $fp = lldb::PDThreadGetRegisterHexValueByName($pid, $tid, $lldb::PD_REGISTER_SET_ALL, "ebp", 0); - # $sp != 0 and printf("fp = 0x%8.8x ", $fp); - # print "\n"; - my $done = 0; - my $input; - while (!$done) - { - print '(pdbg) '; - - chomp($input = <STDIN>); - my @argv = split(/\s+/, $input); - my $cmd = @argv ? shift @argv : undef; - my $cmd_href = get_command_hash_ref ($cmd); - if ($cmd_href) - { - # Print the expanded alias if one was used - if ($opt_v and $cmd_href->{name} ne $cmd) - { - print "$cmd_href->{name} @argv\n"; - } - - # Call the command's callback function to make things happen - if ($cmd_href->{function}($pid, $tid, @argv)) - { - $done = $cmd_href->{runs_target}; - } - } - else - { - print "invalid command: '$cmd'\nType 'help' for a list of all commands.\nType 'help CMD' for help on a specific commmand.\n"; - } - } - } - elsif ( $pid_state == $lldb::eStateRunning || - $pid_state == $lldb::eStateStepping ) - { - - } - elsif ( $pid_state == $lldb::eStateCrashed || - $pid_state == $lldb::eStateDetached || - $pid_state == $lldb::eStateExited ) - { - $pid = 0; - } - elsif ( $pid_state == $lldb::eStateSuspended ) - { - } - else - { - } - } - - if ($pid) - { - $opt_g and printf("PDProcessResetEvents(%d, 0x%8.8x)\n", $pid, $events); - lldb::PDProcessResetEvents($pid, $events); - } - } -} - -if ($pid != $lldb::PD_INVALID_PROCESS_ID) -{ - lldb::PDProcessDetach ($pid); -} diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachException.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachException.cpp deleted file mode 100644 index 3c049f67739..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachException.cpp +++ /dev/null @@ -1,539 +0,0 @@ -//===-- MachException.cpp ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include <errno.h> -#include <sys/types.h> -#include <sys/ptrace.h> - -#include "lldb/Core/StreamString.h" -#include "lldb/Host/Host.h" -#include "StopInfoMachException.h" - -#include "MachException.h" -#include "ProcessMacOSXLog.h" - -using namespace lldb; -using namespace lldb_private; - -// Routine mach_exception_raise -extern "C" -kern_return_t catch_mach_exception_raise -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt -); - -extern "C" -kern_return_t catch_mach_exception_raise_state -( - mach_port_t exception_port, - exception_type_t exception, - const mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - const thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -// Routine mach_exception_raise_state_identity -extern "C" -kern_return_t catch_mach_exception_raise_state_identity -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -extern "C" boolean_t mach_exc_server( - mach_msg_header_t *InHeadP, - mach_msg_header_t *OutHeadP); - -// Any access to the g_message variable should be done by locking the -// g_message_mutex first, using the g_message variable, then unlocking -// the g_message_mutex. See MachException::Message::CatchExceptionRaise() -// for sample code. - -static MachException::Data *g_message = NULL; -//static pthread_mutex_t g_message_mutex = PTHREAD_MUTEX_INITIALIZER; - - -extern "C" -kern_return_t -catch_mach_exception_raise_state -( - mach_port_t exc_port, - exception_type_t exc_type, - const mach_exception_data_t exc_data, - mach_msg_type_number_t exc_data_count, - int * flavor, - const thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t * new_stateCnt -) -{ - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS)); - if (log) - { - log->Printf("::%s ( exc_port = 0x%4.4x, exc_type = %d ( %s ), exc_data = " MACH_EXCEPTION_DATA_FMT_HEX ", exc_data_count = %d)", - __FUNCTION__, - exc_port, - exc_type, MachException::Name(exc_type), - exc_data, - exc_data_count); - } - return KERN_FAILURE; -} - -extern "C" -kern_return_t -catch_mach_exception_raise_state_identity -( - mach_port_t exc_port, - mach_port_t thread_port, - mach_port_t task_port, - exception_type_t exc_type, - mach_exception_data_t exc_data, - mach_msg_type_number_t exc_data_count, - int * flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -) -{ - kern_return_t kret; - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS)); - if (log) - { - log->Printf("::%s ( exc_port = 0x%4.4x, thd_port = 0x%4.4x, tsk_port = 0x%4.4x, exc_type = %d ( %s ), exc_data[%d] = { " MACH_EXCEPTION_DATA_FMT_HEX ", " MACH_EXCEPTION_DATA_FMT_HEX " })", - __FUNCTION__, - exc_port, - thread_port, - task_port, - exc_type, MachException::Name(exc_type), - exc_data_count, - exc_data_count > 0 ? exc_data[0] : 0xBADDBADD, - exc_data_count > 1 ? exc_data[1] : 0xBADDBADD); - } - kret = mach_port_deallocate (mach_task_self (), task_port); - kret = mach_port_deallocate (mach_task_self (), thread_port); - - return KERN_FAILURE; -} - -extern "C" -kern_return_t -catch_mach_exception_raise -( - mach_port_t exc_port, - mach_port_t thread_port, - mach_port_t task_port, - exception_type_t exc_type, - mach_exception_data_t exc_data, - mach_msg_type_number_t exc_data_count) -{ - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS)); - if (log) - { - log->Printf("::%s ( exc_port = 0x%4.4x, thd_port = 0x%4.4x, tsk_port = 0x%4.4x, exc_type = %d ( %s ), exc_data[%d] = { " MACH_EXCEPTION_DATA_FMT_HEX ", " MACH_EXCEPTION_DATA_FMT_HEX " })", - __FUNCTION__, - exc_port, - thread_port, - task_port, - exc_type, MachException::Name(exc_type), - exc_data_count, - exc_data_count > 0 ? exc_data[0] : 0xBADDBADD, - exc_data_count > 1 ? exc_data[1] : 0xBADDBADD); - } - - g_message->task_port = task_port; - g_message->thread_port = thread_port; - g_message->exc_type = exc_type; - g_message->exc_data.resize(exc_data_count); - ::memcpy (&g_message->exc_data[0], exc_data, g_message->exc_data.size() * sizeof (mach_exception_data_type_t)); - return KERN_SUCCESS; -} - - -void -MachException::Message::PutToLog(Log *log) const -{ - if (log) - { - log->Printf(" exc_msg { bits = 0x%8.8lx size = 0x%8.8lx remote-port = 0x%8.8lx local-port = 0x%8.8lx reserved = 0x%8.8lx id = 0x%8.8lx } ", - exc_msg.hdr.msgh_bits, - exc_msg.hdr.msgh_size, - exc_msg.hdr.msgh_remote_port, - exc_msg.hdr.msgh_local_port, - exc_msg.hdr.msgh_reserved, - exc_msg.hdr.msgh_id); - - log->Printf( "reply_msg { bits = 0x%8.8lx size = 0x%8.8lx remote-port = 0x%8.8lx local-port = 0x%8.8lx reserved = 0x%8.8lx id = 0x%8.8lx }", - reply_msg.hdr.msgh_bits, - reply_msg.hdr.msgh_size, - reply_msg.hdr.msgh_remote_port, - reply_msg.hdr.msgh_local_port, - reply_msg.hdr.msgh_reserved, - reply_msg.hdr.msgh_id); - state.PutToLog(log); - } -} - -lldb::StopInfoSP -MachException::Data::GetStopInfo (lldb_private::Thread &thread) const -{ - - const size_t exc_data_count = exc_data.size(); - return StopInfoMachException::CreateStopReasonWithMachException (thread, - exc_type, - exc_data_count, - exc_data_count >= 1 ? exc_data[0] : 0, - exc_data_count >= 2 ? exc_data[1] : 0); -} - - -void -MachException::Data::DumpStopReason() const -{ - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet()); - if (log) - { - int signal = SoftSignal(); - if (signal > 0) - { - const char *signal_str = Host::GetSignalAsCString(signal); - if (signal_str) - log->Printf ("signal(%s)", signal_str); - else - log->Printf ("signal(%i)", signal); - return; - } - log->Printf ("%s", Name(exc_type)); - } -} - -kern_return_t -MachException::Message::Receive(mach_port_t port, mach_msg_option_t options, mach_msg_timeout_t timeout, mach_port_t notify_port) -{ - Error err; - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS)); - mach_msg_timeout_t mach_msg_timeout = options & MACH_RCV_TIMEOUT ? timeout : 0; - if (log && ((options & MACH_RCV_TIMEOUT) == 0)) - { - // Dump this log message if we have no timeout in case it never returns - log->Printf ("::mach_msg ( msg->{bits = %#x, size = %u remote_port = %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, option = %#x, send_size = %u, rcv_size = %u, rcv_name = %#x, timeout = %u, notify = %#x)", - exc_msg.hdr.msgh_bits, - exc_msg.hdr.msgh_size, - exc_msg.hdr.msgh_remote_port, - exc_msg.hdr.msgh_local_port, - exc_msg.hdr.msgh_reserved, - exc_msg.hdr.msgh_id, - options, - 0, - sizeof (exc_msg.data), - port, - mach_msg_timeout, - notify_port); - } - - err = ::mach_msg (&exc_msg.hdr, - options, // options - 0, // Send size - sizeof (exc_msg.data), // Receive size - port, // exception port to watch for exception on - mach_msg_timeout, // timeout in msec (obeyed only if MACH_RCV_TIMEOUT is ORed into the options parameter) - notify_port); - - // Dump any errors we get - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS); - if (log && err.GetError() != MACH_RCV_TIMED_OUT) - { - log->Error("::mach_msg ( msg->{bits = %#x, size = %u remote_port = %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, option = %#x, send_size = %u, rcv_size = %u, rcv_name = %#x, timeout = %u, notify = %#x)", - exc_msg.hdr.msgh_bits, - exc_msg.hdr.msgh_size, - exc_msg.hdr.msgh_remote_port, - exc_msg.hdr.msgh_local_port, - exc_msg.hdr.msgh_reserved, - exc_msg.hdr.msgh_id, - options, - 0, - sizeof (exc_msg.data), - port, - mach_msg_timeout, - notify_port); - } - return err.GetError(); -} - -bool -MachException::Message::CatchExceptionRaise() -{ - bool success = false; - // locker will keep a mutex locked until it goes out of scope -// Mutex::Locker locker(&g_message_mutex); - // log->Printf ("calling mach_exc_server"); - g_message = &state; - // The exc_server function is the MIG generated server handling function - // to handle messages from the kernel relating to the occurrence of an - // exception in a thread. Such messages are delivered to the exception port - // set via thread_set_exception_ports or task_set_exception_ports. When an - // exception occurs in a thread, the thread sends an exception message to - // its exception port, blocking in the kernel waiting for the receipt of a - // reply. The exc_server function performs all necessary argument handling - // for this kernel message and calls catch_exception_raise, - // catch_exception_raise_state or catch_exception_raise_state_identity, - // which should handle the exception. If the called routine returns - // KERN_SUCCESS, a reply message will be sent, allowing the thread to - // continue from the point of the exception; otherwise, no reply message - // is sent and the called routine must have dealt with the exception - // thread directly. - if (mach_exc_server (&exc_msg.hdr, &reply_msg.hdr)) - { - success = true; - } - else - { - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS)); - if (log) - log->Printf ("mach_exc_server returned zero..."); - } - g_message = NULL; - return success; -} - - - -kern_return_t -MachException::Message::Reply(task_t task, pid_t pid, int signal) -{ - // Reply to the exception... - Error err; - - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet()); - if (log) - log->Printf("MachException::Message::Reply (task = 0x%4.4x, pid = %i, signal = %i)", task, pid, signal); - - // If we had a soft signal, we need to update the thread first so it can - // continue without signaling - int soft_signal = state.SoftSignal(); - int state_pid = LLDB_INVALID_PROCESS_ID; - if (task == state.task_port) - { - // This is our task, so we can update the signal to send to it - state_pid = pid; - } - else - { - err = ::pid_for_task(state.task_port, &state_pid); - } - - if (signal == LLDB_INVALID_SIGNAL_NUMBER) - signal = 0; - - if (log) - log->Printf("MachException::Message::Reply () updating thread signal to %i (original soft_signal = %i)", signal, soft_signal); - - if (state_pid != LLDB_INVALID_PROCESS_ID) - { - errno = 0; - if (::ptrace (PT_THUPDATE, state_pid, (caddr_t)state.thread_port, signal) != 0) - { - if (soft_signal != LLDB_INVALID_SIGNAL_NUMBER) - // We know we currently can't forward signals for threads that didn't stop in EXC_SOFT_SIGNAL... - // So only report it as an error if we should have been able to do it. - err.SetErrorToErrno(); - else - err.Clear(); - } - else - err.Clear(); - - if (log && (log->GetMask().Test(PD_LOG_EXCEPTIONS) || err.Fail())) - err.PutToLog(log.get(), "::ptrace (request = PT_THUPDATE, pid = %i, tid = 0x%4.4x, signal = %i)", state_pid, state.thread_port, signal); - } - - err = ::mach_msg ( &reply_msg.hdr, - MACH_SEND_MSG | MACH_SEND_INTERRUPT, - reply_msg.hdr.msgh_size, - 0, - MACH_PORT_NULL, - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - - if (log) - log->LogIf (PD_LOG_EXCEPTIONS, "::mach_msg ( msg->{bits = %#x, size = %u, remote_port = %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, option = %#x, send_size = %u, rcv_size = %u, rcv_name = %#x, timeout = %u, notify = %#x) = 0x%8.8x", - reply_msg.hdr.msgh_bits, - reply_msg.hdr.msgh_size, - reply_msg.hdr.msgh_remote_port, - reply_msg.hdr.msgh_local_port, - reply_msg.hdr.msgh_reserved, - reply_msg.hdr.msgh_id, - MACH_SEND_MSG | MACH_SEND_INTERRUPT, - reply_msg.hdr.msgh_size, - 0, - MACH_PORT_NULL, - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL, - err.GetError()); - - - if (err.Fail()) - { - if (err.GetError() == MACH_SEND_INTERRUPTED) - { - err.PutToLog(log.get(), "::mach_msg() - send interrupted"); - } - else - { - if (state.task_port == task) - { - err.PutToLog(log.get(), "::mach_msg() - failed (task)"); - abort (); - } - else - { - err.PutToLog(log.get(), "::mach_msg() - failed (child of task)"); - } - } - } - - return err.GetError(); -} - - -void -MachException::Data::PutToLog(Log *log) const -{ - if (log == NULL) - return; - - const char *exc_type_name = MachException::Name(exc_type); - - log->Printf (" state { task_port = 0x%4.4x, thread_port = 0x%4.4x, exc_type = %i (%s) ...", task_port, thread_port, exc_type, exc_type_name ? exc_type_name : "???"); - - const size_t exc_data_count = exc_data.size(); - // Dump any special exception data contents - int soft_signal = SoftSignal(); - if (soft_signal > 0) - { - const char *sig_str = Host::GetSignalAsCString(soft_signal); - log->Printf (" exc_data: EXC_SOFT_SIGNAL (%i (%s))", soft_signal, sig_str ? sig_str : "unknown signal"); - } - else - { - // No special disassembly for this data, just dump the data - size_t idx; - for (idx = 0; idx < exc_data_count; ++idx) - { - log->Printf(" exc_data[%u]: " MACH_EXCEPTION_DATA_FMT_HEX, idx, exc_data[idx]); - } - } -} - - -MachException::PortInfo::PortInfo() : - count(0) -{ - ::memset (masks, 0, sizeof(masks)); - ::memset (ports, 0, sizeof(ports)); - ::memset (behaviors, 0, sizeof(behaviors)); - ::memset (flavors, 0, sizeof(flavors)); -} - - -kern_return_t -MachException::PortInfo::Save (task_t task) -{ - count = EXC_TYPES_COUNT; - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_EXCEPTIONS)); - if (log) - log->Printf ("MachException::PortInfo::Save (task = 0x%4.4x)", task); - Error err; - if (log) - log->Printf("::task_get_exception_ports (task=0x%4.4x, mask=0x%x, maskCnt<=>%u, ports, behaviors, flavors)...", task, EXC_MASK_ALL, count); - err = ::task_get_exception_ports (task, EXC_MASK_ALL, masks, &count, ports, behaviors, flavors); - if (log || err.Fail()) - err.PutToLog(log.get(), "::task_get_exception_ports (task=0x%4.4x, mask=0x%x, maskCnt<=>%u, ports, behaviors, flavors)", task, EXC_MASK_ALL, count); - if (log) - { - mach_msg_type_number_t i; - log->Printf("Index Mask Port Behavior Flavor", masks[i], ports[i], behaviors[i], flavors[i]); - log->Printf("===== -------- -------- -------- --------"); - for (i=0; i<count; ++i) - log->Printf("[%3u] %8.8x %8.8x %8.8x %8.8x", i, masks[i], ports[i], behaviors[i], flavors[i]); - } - if (err.Fail()) - count = 0; - return err.GetError(); -} - -kern_return_t -MachException::PortInfo::Restore (task_t task) -{ - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_EXCEPTIONS)); - if (log && log->GetMask().Test(PD_LOG_VERBOSE)) - log->Printf("MachException::PortInfo::Restore (task = 0x%4.4x)", task); - uint32_t i = 0; - Error err; - if (count > 0) - { - for (i = 0; i < count; i++) - { - err = ::task_set_exception_ports (task, masks[i], ports[i], behaviors[i], flavors[i]); - if (log || err.Fail()) - err.PutToLog(log.get(), "::task_set_exception_ports ( task = 0x%4.4x, exception_mask = 0x%8.8x, new_port = 0x%4.4x, behavior = 0x%8.8x, new_flavor = 0x%8.8x )", task, masks[i], ports[i], behaviors[i], flavors[i]); - - if (err.Fail()) - break; - } - } - count = 0; - return err.GetError(); -} - -const char * -MachException::Name(exception_type_t exc_type) -{ - switch (exc_type) - { - case EXC_BAD_ACCESS: return "EXC_BAD_ACCESS"; - case EXC_BAD_INSTRUCTION: return "EXC_BAD_INSTRUCTION"; - case EXC_ARITHMETIC: return "EXC_ARITHMETIC"; - case EXC_EMULATION: return "EXC_EMULATION"; - case EXC_SOFTWARE: return "EXC_SOFTWARE"; - case EXC_BREAKPOINT: return "EXC_BREAKPOINT"; - case EXC_SYSCALL: return "EXC_SYSCALL"; - case EXC_MACH_SYSCALL: return "EXC_MACH_SYSCALL"; - case EXC_RPC_ALERT: return "EXC_RPC_ALERT"; -#ifdef EXC_CRASH - case EXC_CRASH: return "EXC_CRASH"; -#endif - default: - break; - } - return NULL; -} - - - diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachException.h b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachException.h deleted file mode 100644 index 761f433405b..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachException.h +++ /dev/null @@ -1,148 +0,0 @@ -//===-- MachException.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_MachException_h_ -#define liblldb_MachException_h_ - -#include <mach/mach.h> -#include <vector> -#include "lldb/lldb-private.h" -#include "lldb/Target/Thread.h" -// TODO: Get the config script to run to this plug-in -//#include "PDConfig.h" -#define HAVE_64_BIT_MACH_EXCEPTIONS // REMOVE THIS WHEN PDConfig.h is included above -#ifdef HAVE_64_BIT_MACH_EXCEPTIONS - -#define MACH_EXCEPTION_DATA_FMT_DEC "%lld" -#define MACH_EXCEPTION_DATA_FMT_HEX "0x%16.16llx" -#define MACH_EXCEPTION_DATA_FMT_MINHEX "0x%llx" - -#else - -#define MACH_EXCEPTION_DATA_FMT_DEC "%d" -#define MACH_EXCEPTION_DATA_FMT_HEX "0x%8.8x" -#define MACH_EXCEPTION_DATA_FMT_MINHEX "0x%x" - -#endif - -class MachProcess; - -typedef union MachMessageTag -{ - mach_msg_header_t hdr; - char data[1024]; -} MachMessage; - - -class MachException -{ -public: - - struct PortInfo - { - exception_mask_t masks[EXC_TYPES_COUNT]; - mach_port_t ports[EXC_TYPES_COUNT]; - exception_behavior_t behaviors[EXC_TYPES_COUNT]; - thread_state_flavor_t flavors[EXC_TYPES_COUNT]; - mach_msg_type_number_t count; - - PortInfo(); - kern_return_t Save(task_t task); - kern_return_t Restore(task_t task); - }; - - struct Data - { - task_t task_port; - lldb::tid_t thread_port; - exception_type_t exc_type; - std::vector<lldb::addr_t> exc_data; - Data() : - task_port(TASK_NULL), - thread_port(THREAD_NULL), - exc_type(0), - exc_data() - { - } - - void Clear() - { - task_port = TASK_NULL; - thread_port = THREAD_NULL; - exc_type = 0; - exc_data.clear(); - } - bool IsValid() const - { - return task_port != TASK_NULL && - thread_port != THREAD_NULL && - exc_type != 0; - } - // Return the SoftSignal for this MachException data, or zero if there is none - int SoftSignal() const - { - if (exc_type == EXC_SOFTWARE && exc_data.size() == 2 && exc_data[0] == EXC_SOFT_SIGNAL) - return exc_data[1]; - return LLDB_INVALID_SIGNAL_NUMBER; - } - bool IsBreakpoint() const - { - return (exc_type == EXC_BREAKPOINT) || ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1); - } - void PutToLog(lldb_private::Log *log) const; - void DumpStopReason() const; - lldb::StopInfoSP GetStopInfo (lldb_private::Thread &thread) const; - }; - - struct Message - { - MachMessage exc_msg; - MachMessage reply_msg; - Data state; - - Message() : - exc_msg(), - reply_msg(), - state() - { - memset(&exc_msg, 0, sizeof(exc_msg)); - memset(&reply_msg, 0, sizeof(reply_msg)); - } - bool CatchExceptionRaise(); - void PutToLog(lldb_private::Log *log) const; - kern_return_t Reply (task_t task, pid_t pid, int signal); - kern_return_t Receive( mach_port_t receive_port, - mach_msg_option_t options, - mach_msg_timeout_t timeout, - mach_port_t notify_port = MACH_PORT_NULL); - - typedef std::vector<Message> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; - }; - - enum - { - e_actionForward, // Forward signal to inferior process - e_actionStop // Stop when this signal is received - }; - struct Action - { - task_t task_port; // Set to TASK_NULL for any TASK - lldb::tid_t thread_port; // Set to THREAD_NULL for any thread - exception_type_t exc_mask; // Mach exception mask to watch for - std::vector<mach_exception_data_type_t> exc_data_mask; // Mask to apply to exception data, or empty to ignore exc_data value for exception - std::vector<mach_exception_data_type_t> exc_data_value; // Value to compare to exception data after masking, or empty to ignore exc_data value for exception - uint8_t flags; // Action flags describing what to do with the exception - }; - static const char *Name(exception_type_t exc_type); -}; - -#endif diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachTask.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachTask.cpp deleted file mode 100644 index feb3300d572..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachTask.cpp +++ /dev/null @@ -1,680 +0,0 @@ -//===-- MachTask.cpp --------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "MachTask.h" - -// C Includes -// C++ Includes - -// Other libraries and framework includes -#if defined (__arm__) - -#include <CoreFoundation/CoreFoundation.h> -#include <SpringBoardServices/SpringBoardServer.h> -#include <SpringBoardServices/SBSWatchdogAssertion.h> - -#endif - -#include "lldb/Host/Endian.h" -#include "lldb/Host/Host.h" -#include "lldb/Core/DataExtractor.h" - -// Project includes -#include "ProcessMacOSX.h" -#include "ProcessMacOSXLog.h" - - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// MachTask constructor -//---------------------------------------------------------------------- -MachTask::MachTask(ProcessMacOSX *process) : - m_process (process), - m_task (TASK_NULL), - m_vm_memory (), - m_exc_port_info(), - m_exception_thread (0), - m_exception_port (MACH_PORT_NULL) -{ - memset(&m_exc_port_info, 0, sizeof(m_exc_port_info)); - -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -MachTask::~MachTask() -{ - Clear(); -} - - -//---------------------------------------------------------------------- -// MachTask::Suspend -//---------------------------------------------------------------------- -kern_return_t -MachTask::Suspend() -{ - Error err; - task_t task = GetTaskPort(); - err = ::task_suspend (task); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_TASK)); - if (log || err.Fail()) - err.PutToLog(log.get(), "::task_suspend ( target_task = 0x%4.4x )", task); - return err.GetError(); -} - - -//---------------------------------------------------------------------- -// MachTask::Resume -//---------------------------------------------------------------------- -kern_return_t -MachTask::Resume() -{ - Error err; - task_t task = GetTaskPort(); - err = ::task_resume (task); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_TASK)); - if (log || err.Fail()) - err.PutToLog(log.get(), "::task_resume ( target_task = 0x%4.4x )", task); - return err.GetError(); -} - -int32_t -MachTask::GetSuspendCount () const -{ - struct task_basic_info task_info; - if (BasicInfo(&task_info) == KERN_SUCCESS) - return task_info.suspend_count; - return -1; -} - -//---------------------------------------------------------------------- -// MachTask::ExceptionPort -//---------------------------------------------------------------------- -mach_port_t -MachTask::ExceptionPort() const -{ - return m_exception_port; -} - -//---------------------------------------------------------------------- -// MachTask::ExceptionPortIsValid -//---------------------------------------------------------------------- -bool -MachTask::ExceptionPortIsValid() const -{ - return MACH_PORT_VALID(m_exception_port); -} - - -//---------------------------------------------------------------------- -// MachTask::Clear -//---------------------------------------------------------------------- -void -MachTask::Clear() -{ - // Do any cleanup needed for this task - m_task = TASK_NULL; - m_exception_thread = 0; - m_exception_port = MACH_PORT_NULL; - -} - - -//---------------------------------------------------------------------- -// MachTask::SaveExceptionPortInfo -//---------------------------------------------------------------------- -kern_return_t -MachTask::SaveExceptionPortInfo() -{ - return m_exc_port_info.Save(GetTaskPort()); -} - -//---------------------------------------------------------------------- -// MachTask::RestoreExceptionPortInfo -//---------------------------------------------------------------------- -kern_return_t -MachTask::RestoreExceptionPortInfo() -{ - return m_exc_port_info.Restore(GetTaskPort()); -} - - -//---------------------------------------------------------------------- -// MachTask::ReadMemory -//---------------------------------------------------------------------- -size_t -MachTask::ReadMemory (lldb::addr_t addr, void *buf, size_t size, Error& error) -{ - size_t n = 0; - task_t task = GetTaskPort(); - if (task != TASK_NULL) - { - n = m_vm_memory.Read(task, addr, buf, size, error); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_MEMORY)); - if (log) - { - log->Printf ("MachTask::ReadMemory ( addr = 0x%16.16llx, size = %zu, buf = %8.8p) => %u bytes read", (uint64_t)addr, size, buf, n); - if (log->GetMask().Test(PD_LOG_MEMORY_DATA_LONG) || (log->GetMask().Test(PD_LOG_MEMORY_DATA_SHORT) && size <= 8)) - { - DataExtractor data((uint8_t*)buf, n, lldb::endian::InlHostByteOrder(), 4); - data.PutToLog(log.get(), 0, n, addr, 16, DataExtractor::TypeUInt8); - } - } - } - return n; -} - - -//---------------------------------------------------------------------- -// MachTask::WriteMemory -//---------------------------------------------------------------------- -size_t -MachTask::WriteMemory (lldb::addr_t addr, const void *buf, size_t size, Error& error) -{ - size_t n = 0; - task_t task = GetTaskPort(); - if (task != TASK_NULL) - { - n = m_vm_memory.Write(task, addr, buf, size, error); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_MEMORY)); - if (log) - { - log->Printf ("MachTask::WriteMemory ( addr = 0x%16.16llx, size = %zu, buf = %8.8p) => %u bytes written", (uint64_t)addr, size, buf, n); - if (log->GetMask().Test(PD_LOG_MEMORY_DATA_LONG) || (log->GetMask().Test(PD_LOG_MEMORY_DATA_SHORT) && size <= 8)) - { - DataExtractor data((uint8_t*)buf, n, lldb::endian::InlHostByteOrder(), 4); - data.PutToLog(log.get(), 0, n, addr, 16, DataExtractor::TypeUInt8); - } - } - } - return n; -} - -//---------------------------------------------------------------------- -// MachTask::AllocateMemory -//---------------------------------------------------------------------- -lldb::addr_t -MachTask::AllocateMemory (size_t size, uint32_t permissions, Error& error) -{ - // FIXME: vm_allocate allocates a page at a time, so we should use - // host_page_size to get the host page size and then parcel out the - // page we get back until it is filled. - // FIXME: Add log messages. - - kern_return_t kret; - mach_vm_address_t addr; - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_MEMORY)); - - kret = ::mach_vm_allocate (GetTaskPort(), &addr, size, TRUE); - if (kret == KERN_SUCCESS) - { - // Set the protections: - vm_prot_t mach_prot = 0; - if (permissions & lldb::ePermissionsReadable) - mach_prot |= VM_PROT_READ; - if (permissions & lldb::ePermissionsWritable) - mach_prot |= VM_PROT_WRITE; - if (permissions & lldb::ePermissionsExecutable) - mach_prot |= VM_PROT_EXECUTE; - - kret = ::mach_vm_protect (GetTaskPort(), addr, size, 0, mach_prot); - if (kret == KERN_SUCCESS) - { - if (log) - log->Printf("Allocated memory at addr = 0x%16.16llx, size = %zu, prot = 0x%x)", (uint64_t) addr, size, mach_prot); - m_allocations.insert (std::make_pair(addr, size)); - return (lldb::addr_t) addr; - } - else - { - if (log) - log->Printf("Failed to set protections on memory at addr = 0x%16.16llx, size = %zu), prot = 0x%x", (uint64_t) addr, size, mach_prot); - kret = ::mach_vm_deallocate (GetTaskPort(), addr, size); - return LLDB_INVALID_ADDRESS; - } - } - else - { - if (log) - log->Printf("Failed to set allocate memory: size = %zu)", size); - return LLDB_INVALID_ADDRESS; - } -} - -//---------------------------------------------------------------------- -// MachTask::DeallocateMemory -//---------------------------------------------------------------------- -Error -MachTask::DeallocateMemory (lldb::addr_t ptr) -{ - Error error; - // We have to stash away sizes for the allocations... - allocation_collection::iterator pos, end = m_allocations.end(); - for (pos = m_allocations.begin(); pos != end; pos++) - { - if ((*pos).first == ptr) - { - m_allocations.erase (pos); - error = ::mach_vm_deallocate (GetTaskPort(), (vm_address_t) ptr, (*pos).second); - return error; - } - } - error.SetErrorStringWithFormat("no memory allocated at 0x%llx", (uint64_t)ptr); - return error; -} - -//---------------------------------------------------------------------- -// MachTask::TaskPortForProcessID -//---------------------------------------------------------------------- -task_t -MachTask::GetTaskPortForProcessID (Error &err) -{ - err.Clear(); - if (m_task == TASK_NULL && m_process != NULL) - m_task = MachTask::GetTaskPortForProcessID(m_process->GetID(), err); - return m_task; -} - -//---------------------------------------------------------------------- -// MachTask::TaskPortForProcessID -//---------------------------------------------------------------------- -task_t -MachTask::GetTaskPortForProcessID (lldb::pid_t pid, Error &err) -{ - task_t task = TASK_NULL; - if (pid != LLDB_INVALID_PROCESS_ID) - { - mach_port_t task_self = mach_task_self (); - err = ::task_for_pid ( task_self, pid, &task); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_TASK)); - if (log || err.Fail()) - { - err.PutToLog(log.get(), "::task_for_pid ( target_tport = 0x%4.4x, pid = %d, task => 0x%4.4x ) %u/%u %u/%u", task_self, pid, task, getuid(), geteuid(), getgid(), getegid()); - } - } - return task; -} - - -//---------------------------------------------------------------------- -// MachTask::BasicInfo -//---------------------------------------------------------------------- -kern_return_t -MachTask::BasicInfo(struct task_basic_info *info) const -{ - return BasicInfo (GetTaskPort(), info); -} - -//---------------------------------------------------------------------- -// MachTask::BasicInfo -//---------------------------------------------------------------------- -kern_return_t -MachTask::BasicInfo(task_t task, struct task_basic_info *info) -{ - if (info == NULL) - return KERN_INVALID_ARGUMENT; - - Error err; - mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT; - err = ::task_info (task, TASK_BASIC_INFO, (task_info_t)info, &count); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_TASK)); - if (log || err.Fail()) - err.PutToLog(log.get(), "::task_info ( target_task = 0x%4.4x, flavor = TASK_BASIC_INFO, task_info_out => %p, task_info_outCnt => %u )", task, info, count); - if (log && log->GetMask().Test(PD_LOG_VERBOSE) && err.Success()) - { - float user = (float)info->user_time.seconds + (float)info->user_time.microseconds / 1000000.0f; - float system = (float)info->user_time.seconds + (float)info->user_time.microseconds / 1000000.0f; - log->Printf ("task_basic_info = { suspend_count = %i, virtual_size = 0x%8.8x, resident_size = 0x%8.8x, user_time = %f, system_time = %f }", - info->suspend_count, info->virtual_size, info->resident_size, user, system); - } - return err.GetError(); -} - - -//---------------------------------------------------------------------- -// MachTask::IsValid -// -// Returns true if a task is a valid task port for a current process. -//---------------------------------------------------------------------- -bool -MachTask::IsValid () const -{ - return MachTask::IsValid(GetTaskPort()); -} - -//---------------------------------------------------------------------- -// MachTask::IsValid -// -// Returns true if a task is a valid task port for a current process. -//---------------------------------------------------------------------- -bool -MachTask::IsValid (task_t task) -{ - if (task != TASK_NULL) - { - struct task_basic_info task_info; - return BasicInfo(task, &task_info) == KERN_SUCCESS; - } - return false; -} - - -bool -MachTask::StartExceptionThread(Error &err) -{ - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_EXCEPTIONS)); - - if (log) - log->Printf ("MachTask::%s ( )", __FUNCTION__); - task_t task = GetTaskPortForProcessID(err); - if (MachTask::IsValid(task)) - { - // Got the mach port for the current process - mach_port_t task_self = mach_task_self (); - - // Allocate an exception port that we will use to track our child process - err = ::mach_port_allocate (task_self, MACH_PORT_RIGHT_RECEIVE, &m_exception_port); - if (log || err.Fail()) - err.PutToLog(log.get(), "::mach_port_allocate (task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, &m_exception_port => 0x%4.4x)", - task_self, m_exception_port); - if (err.Fail()) - return false; - - // Add the ability to send messages on the new exception port - err = ::mach_port_insert_right (task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND); - if (log || err.Fail()) - err.PutToLog(log.get(), "::mach_port_insert_right (task_self=0x%4.4x, m_exception_port=0x%4.4x, m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND)", - task_self, m_exception_port, m_exception_port); - if (err.Fail()) - return false; - - // Save the original state of the exception ports for our child process - err = SaveExceptionPortInfo(); - - // Set the ability to get all exceptions on this port - err = ::task_set_exception_ports (task, EXC_MASK_ALL, m_exception_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE); - if (log || err.Fail()) - err.PutToLog(log.get(), "::task_set_exception_ports (task, EXC_MASK_ALL, m_exception_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE)"); - if (err.Fail()) - return false; - - // Create the exception thread - char thread_name[256]; - ::snprintf (thread_name, sizeof(thread_name), "<lldb.process.process-macosx.mach-exception-%d>", m_process->GetID()); - m_exception_thread = Host::ThreadCreate (thread_name, MachTask::ExceptionThread, this, &err); - - return err.Success(); - } - return false; -} - -kern_return_t -MachTask::ShutDownExceptionThread() -{ - Error err; - - if (m_exception_thread == NULL) - return KERN_SUCCESS; - - err = RestoreExceptionPortInfo(); - - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_EXCEPTIONS)); - - // NULL our our exception port and let our exception thread exit - mach_port_t exception_port = m_exception_port; - m_exception_port = NULL; - - Host::ThreadCancel (m_exception_thread, &err); - if (log || err.Fail()) - err.PutToLog(log.get(), "Host::ThreadCancel ( thread = %p )", m_exception_thread); - - Host::ThreadJoin (m_exception_thread, NULL, &err); - if (log || err.Fail()) - err.PutToLog(log.get(), "Host::ThreadJoin ( thread = %p, result_ptr = NULL)", m_exception_thread); - - // Deallocate our exception port that we used to track our child process - mach_port_t task_self = mach_task_self (); - err = ::mach_port_deallocate (task_self, exception_port); - if (log || err.Fail()) - err.PutToLog(log.get(), "::mach_port_deallocate ( task = 0x%4.4x, name = 0x%4.4x )", task_self, exception_port); - exception_port = NULL; - - Clear(); - return err.GetError(); -} - - -void * -MachTask::ExceptionThread (void *arg) -{ - if (arg == NULL) - return NULL; - - MachTask *mach_task = (MachTask*) arg; - ProcessMacOSX *mach_proc = mach_task->Process(); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_EXCEPTIONS)); - if (log) - log->Printf ("MachTask::%s (arg = %p) thread starting...", __FUNCTION__, arg); - - // We keep a count of the number of consecutive exceptions received so - // we know to grab all exceptions without a timeout. We do this to get a - // bunch of related exceptions on our exception port so we can process - // then together. When we have multiple threads, we can get an exception - // per thread and they will come in consecutively. The main loop in this - // thread can stop periodically if needed to service things related to this - // process. - // flag set in the options, so we will wait forever for an exception on - // our exception port. After we get one exception, we then will use the - // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current - // exceptions for our process. After we have received the last pending - // exception, we will get a timeout which enables us to then notify - // our main thread that we have an exception bundle available. We then wait - // for the main thread to tell this exception thread to start trying to get - // exceptions messages again and we start again with a mach_msg read with - // infinite timeout. - uint32_t num_exceptions_received = 0; - Error err; - task_t task = mach_task->GetTaskPort(); - mach_msg_timeout_t periodic_timeout = 1000; - -#if defined (__arm__) - mach_msg_timeout_t watchdog_elapsed = 0; - mach_msg_timeout_t watchdog_timeout = 60 * 1000; - lldb::pid_t pid = mach_proc->GetID(); - CFReleaser<SBSWatchdogAssertionRef> watchdog; - - if (mach_proc->ProcessUsingSpringBoard()) - { - // Request a renewal for every 60 seconds if we attached using SpringBoard - watchdog.reset(::SBSWatchdogAssertionCreateForPID(NULL, pid, 60)); - if (log) - log->Printf ("::SBSWatchdogAssertionCreateForPID (NULL, %4.4x, 60 ) => %p", pid, watchdog.get()); - - if (watchdog.get()) - { - ::SBSWatchdogAssertionRenew (watchdog.get()); - - CFTimeInterval watchdogRenewalInterval = ::SBSWatchdogAssertionGetRenewalInterval (watchdog.get()); - if (log) - log->Printf ("::SBSWatchdogAssertionGetRenewalInterval ( %p ) => %g seconds", watchdog.get(), watchdogRenewalInterval); - if (watchdogRenewalInterval > 0.0) - { - watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000; - if (watchdog_timeout > 3000) - watchdog_timeout -= 1000; // Give us a second to renew our timeout - else if (watchdog_timeout > 1000) - watchdog_timeout -= 250; // Give us a quarter of a second to renew our timeout - } - } - if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout) - periodic_timeout = watchdog_timeout; - } -#endif // #if defined (__arm__) - - while (mach_task->ExceptionPortIsValid()) - { - //::pthread_testcancel (); - - MachException::Message exception_message; - - - if (num_exceptions_received > 0) - { - // No timeout, just receive as many exceptions as we can since we already have one and we want - // to get all currently available exceptions for this task - err = exception_message.Receive(mach_task->ExceptionPort(), MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0); - } - else if (periodic_timeout > 0) - { - // We need to stop periodically in this loop, so try and get a mach message with a valid timeout (ms) - err = exception_message.Receive(mach_task->ExceptionPort(), MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, periodic_timeout); - } - else - { - // We don't need to parse all current exceptions or stop periodically, - // just wait for an exception forever. - err = exception_message.Receive(mach_task->ExceptionPort(), MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0); - } - - if (err.GetError() == MACH_RCV_INTERRUPTED) - { - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_EXCEPTIONS); - // If we have no task port we should exit this thread - if (!mach_task->ExceptionPortIsValid()) - { - if (log) - log->Printf ("thread cancelled..."); - break; - } - - // Make sure our task is still valid - if (MachTask::IsValid(task)) - { - // Task is still ok - if (log) - log->Printf ("interrupted, but task still valid, continuing..."); - continue; - } - else - { - if (log) - log->Printf ("task has exited..."); - mach_proc->SetPrivateState (eStateExited); - // Our task has died, exit the thread. - break; - } - } - else if (err.GetError() == MACH_RCV_TIMED_OUT) - { - if (num_exceptions_received > 0) - { - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_EXCEPTIONS); - - // We were receiving all current exceptions with a timeout of zero - // it is time to go back to our normal looping mode - num_exceptions_received = 0; - - // Notify our main thread we have a complete exception message - // bundle available. - mach_proc->ExceptionMessageBundleComplete(); - - // in case we use a timeout value when getting exceptions... - // Make sure our task is still valid - if (MachTask::IsValid(task)) - { - // Task is still ok - if (log) - log->Printf ("got a timeout, continuing..."); - continue; - } - else - { - if (log) - log->Printf ("task has exited..."); - mach_proc->SetPrivateState (eStateExited); - // Our task has died, exit the thread. - break; - } - continue; - } - -#if defined (__arm__) - if (watchdog.get()) - { - watchdog_elapsed += periodic_timeout; - if (watchdog_elapsed >= watchdog_timeout) - { - LogIf(PD_LOG_TASK, "SBSWatchdogAssertionRenew ( %p )", watchdog.get()); - ::SBSWatchdogAssertionRenew (watchdog.get()); - watchdog_elapsed = 0; - } - } -#endif - } - else if (err.GetError() != KERN_SUCCESS) - { - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_EXCEPTIONS); - if (log) - log->Printf ("got some other error, do something about it??? nah, continuing for now..."); - // TODO: notify of error? - } - else - { - if (exception_message.CatchExceptionRaise()) - { - ++num_exceptions_received; - mach_proc->ExceptionMessageReceived(exception_message); - } - } - } - -#if defined (__arm__) - if (watchdog.get()) - { - // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel when we - // all are up and running on systems that support it. The SBS framework has a #define - // that will forward SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel for now - // so it should still build either way. - LogIf(PD_LOG_TASK, "::SBSWatchdogAssertionRelease(%p)", watchdog.get()); - ::SBSWatchdogAssertionRelease (watchdog.get()); - } -#endif // #if defined (__arm__) - - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_EXCEPTIONS); - if (log) - log->Printf ("MachTask::%s (arg = %p) thread exiting...", __FUNCTION__, arg); - return NULL; -} - -lldb::addr_t -MachTask::GetDYLDAllImageInfosAddress () -{ -#ifdef TASK_DYLD_INFO - task_dyld_info_data_t dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - Error err; - // The actual task shouldn't matter for the DYLD info, so lets just use ours - kern_return_t kret = ::task_info (GetTaskPortForProcessID (err), TASK_DYLD_INFO, (task_info_t)&dyld_info, &count); - if (kret == KERN_SUCCESS) - { - // We now have the address of the all image infos structure - return dyld_info.all_image_info_addr; - } -#endif - return LLDB_INVALID_ADDRESS; -} - - - - - diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachTask.h b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachTask.h deleted file mode 100644 index 228cb7c516b..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachTask.h +++ /dev/null @@ -1,138 +0,0 @@ -//===-- MachTask.h ----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef __MachTask_h__ -#define __MachTask_h__ - -// C Includes -// C++ Includes -#include <map> -// Other libraries and framework includes -#include <mach/mach.h> -#include <mach/mach_vm.h> -#include <sys/socket.h> - -// Project includes -#include "MachException.h" -#include "MachVMMemory.h" - -class ProcessMacOSX; - -class MachTask -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - MachTask (ProcessMacOSX *process); - - virtual - ~MachTask (); - - void - Clear (); - - kern_return_t - Suspend (); - - kern_return_t - Resume (); - - int32_t - GetSuspendCount () const; - - size_t - ReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error& error); - - size_t - WriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error& error); - - lldb::addr_t - AllocateMemory (size_t size, uint32_t permissions, lldb_private::Error& error); - - lldb_private::Error - DeallocateMemory (lldb::addr_t addr); - - mach_port_t - ExceptionPort () const; - - bool - ExceptionPortIsValid () const; - - kern_return_t - SaveExceptionPortInfo (); - - kern_return_t - RestoreExceptionPortInfo (); - - kern_return_t - ShutDownExceptionThread (); - - bool - StartExceptionThread (lldb_private::Error &err); - - lldb::addr_t - GetDYLDAllImageInfosAddress (); - - kern_return_t - BasicInfo (struct task_basic_info *info) const; - - static kern_return_t - BasicInfo (task_t task, struct task_basic_info *info); - - bool - IsValid () const; - - static bool - IsValid (task_t task); - - static void * - ExceptionThread (void *arg); - - task_t - GetTaskPort () const - { - return m_task; - } - - task_t - GetTaskPortForProcessID (lldb_private::Error &err); - - static task_t - GetTaskPortForProcessID (lldb::pid_t pid, lldb_private::Error &err); - - ProcessMacOSX * - Process () - { - return m_process; - } - - const ProcessMacOSX * - Process () const - { - return m_process; - } - -protected: - ProcessMacOSX * m_process; // The mach process that owns this MachTask - task_t m_task; - MachVMMemory m_vm_memory; // Special mach memory reading class that will take care of watching for page and region boundaries - MachException::PortInfo m_exc_port_info; // Saved settings for all exception ports - lldb::thread_t m_exception_thread; // Thread ID for the exception thread in case we need it - mach_port_t m_exception_port; // Exception port on which we will receive child exceptions - - // Maybe sort this by address and use find? - typedef std::map<vm_address_t,size_t> allocation_collection; - allocation_collection m_allocations; - -private: - DISALLOW_COPY_AND_ASSIGN (MachTask); -}; - -#endif // __MachTask_h__ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext.h b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext.h deleted file mode 100644 index 4141ea391f0..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext.h +++ /dev/null @@ -1,48 +0,0 @@ -//===-- MachThreadContext.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_MachThreadContext_h_ -#define liblldb_MachThreadContext_h_ - -#include <vector> - -#include "MachException.h" - -class ThreadMacOSX; - -class MachThreadContext -{ -public: - MachThreadContext (ThreadMacOSX &thread) : - m_thread (thread) - { - } - - virtual ~MachThreadContext() - { - } - - virtual lldb::RegisterContextSP - CreateRegisterContext (lldb_private::StackFrame *frame) const = 0; - - virtual void InitializeInstance() = 0; - virtual void ThreadWillResume () = 0; - virtual bool ShouldStop () = 0; - virtual void RefreshStateAfterStop() = 0; - virtual bool NotifyException (MachException::Data& exc) { return false; } - virtual bool StepNotComplete () { return false; } - virtual size_t GetStackFrameData(lldb_private::StackFrame *frame, std::vector<std::pair<lldb::addr_t, lldb::addr_t> >& fp_pc_pairs) { return 0; } -// virtual const uint8_t * SoftwareBreakpointOpcode (size_t byte_size) = 0; - -protected: - ThreadMacOSX &m_thread; - -}; - -#endif // #ifndef liblldb_MachThreadContext_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_arm.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_arm.cpp deleted file mode 100644 index 5ceedc0bb58..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_arm.cpp +++ /dev/null @@ -1,1878 +0,0 @@ -//===-- MachThreadContext_arm.cpp -------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "MachThreadContext_arm.h" - -#include <sys/sysctl.h> - -#include "ProcessMacOSX.h" -#include "ProcessMacOSXLog.h" -#include "ThreadMacOSX.h" - -using namespace lldb_private; - -//#define DNB_ARCH_MACH_ARM_DEBUG_SW_STEP 1 - -static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; -static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE }; - -// ARM constants used during decoding -#define REG_RD 0 -#define LDM_REGLIST 1 -#define PC_REG 15 -#define PC_REGLIST_BIT 0x8000 - -// ARM conditions -#define COND_EQ 0x0 -#define COND_NE 0x1 -#define COND_CS 0x2 -#define COND_HS 0x2 -#define COND_CC 0x3 -#define COND_LO 0x3 -#define COND_MI 0x4 -#define COND_PL 0x5 -#define COND_VS 0x6 -#define COND_VC 0x7 -#define COND_HI 0x8 -#define COND_LS 0x9 -#define COND_GE 0xA -#define COND_LT 0xB -#define COND_GT 0xC -#define COND_LE 0xD -#define COND_AL 0xE -#define COND_UNCOND 0xF - -#define MASK_CPSR_T (1u << 5) -#define MASK_CPSR_J (1u << 24) - -#define MNEMONIC_STRING_SIZE 32 -#define OPERAND_STRING_SIZE 128 - -using namespace lldb; -using namespace lldb_private; - -MachThreadContext_arm::MachThreadContext_arm(ThreadMacOSX &thread) : - MachThreadContext(thread), - m_hw_single_chained_step_addr(LLDB_INVALID_ADDRESS), - m_bvr0_reg (LLDB_INVALID_REGNUM), - m_bcr0_reg (LLDB_INVALID_REGNUM), - m_bvr0_save (0), - m_bcr0_save (0) -{ -} - -MachThreadContext_arm::~MachThreadContext_arm() -{ -} - -lldb::RegisterContextSP -MachThreadContext_arm::CreateRegisterContext (StackFrame *frame) const -{ - lldb::RegisterContextSP reg_ctx_sp (new RegisterContextMach_arm(m_thread, frame->GetConcreteFrameIndex())); - return reg_ctx_sp; -} - -// Instance init function -void -MachThreadContext_arm::InitializeInstance() -{ - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx != NULL); - const RegisterInfo * reg_info; - reg_info = reg_ctx->GetRegisterInfoByName ("bvr0"); - if (reg_info) - m_bvr0_reg = reg_info->kinds[eRegisterKindLLDB]; - - reg_info = reg_ctx->GetRegisterInfoByName ("bcr0"); - if (reg_info) - m_bcr0_reg = reg_info->kinds[eRegisterKindLLDB]; -} - - -void -MachThreadContext_arm::ThreadWillResume() -{ - // Do we need to step this thread? If so, let the mach thread tell us so. - if (m_thread.GetState() == eStateStepping) - { - bool step_handled = false; - // This is the primary thread, let the arch do anything it needs - if (m_thread.GetRegisterContext()->NumSupportedHardwareBreakpoints() > 0) - { -#if defined (DNB_ARCH_MACH_ARM_DEBUG_SW_STEP) - bool half_step = m_hw_single_chained_step_addr != LLDB_INVALID_ADDRESS; -#endif - step_handled = EnableHardwareSingleStep(true) == KERN_SUCCESS; -#if defined (DNB_ARCH_MACH_ARM_DEBUG_SW_STEP) - if (!half_step) - step_handled = false; -#endif - } - -#if defined (ENABLE_ARM_SINGLE_STEP) - if (!step_handled) - { - SetSingleStepSoftwareBreakpoints(); - } -#endif - } -} - -bool -MachThreadContext_arm::ShouldStop () -{ - return true; -} - -void -MachThreadContext_arm::RefreshStateAfterStop () -{ - EnableHardwareSingleStep (false); -} - -#if defined (ENABLE_ARM_SINGLE_STEP) - -bool -MachThreadContext_arm::ShouldStop () -{ - return true; -} - -bool -MachThreadContext_arm::RefreshStateAfterStop () -{ - success = EnableHardwareSingleStep(false) == KERN_SUCCESS; - - bool success = true; - - m_state.InvalidateRegisterSet (GPRRegSet); - m_state.InvalidateRegisterSet (VFPRegSet); - m_state.InvalidateRegisterSet (EXCRegSet); - - // Are we stepping a single instruction? - if (ReadGPRRegisters(true) == KERN_SUCCESS) - { - // We are single stepping, was this the primary thread? - if (m_thread.GetState() == eStateStepping) - { -#if defined (DNB_ARCH_MACH_ARM_DEBUG_SW_STEP) - success = EnableHardwareSingleStep(false) == KERN_SUCCESS; - // Hardware single step must work if we are going to test software - // single step functionality - assert(success); - if (m_hw_single_chained_step_addr == LLDB_INVALID_ADDRESS && m_sw_single_step_next_pc != LLDB_INVALID_ADDRESS) - { - uint32_t sw_step_next_pc = m_sw_single_step_next_pc & 0xFFFFFFFEu; - bool sw_step_next_pc_is_thumb = (m_sw_single_step_next_pc & 1) != 0; - bool actual_next_pc_is_thumb = (m_state.gpr.__cpsr & 0x20) != 0; - if (m_state.gpr.r[15] != sw_step_next_pc) - { - LogError("curr pc = 0x%8.8x - calculated single step target PC was incorrect: 0x%8.8x != 0x%8.8x", m_state.gpr.r[15], sw_step_next_pc, m_state.gpr.r[15]); - exit(1); - } - if (actual_next_pc_is_thumb != sw_step_next_pc_is_thumb) - { - LogError("curr pc = 0x%8.8x - calculated single step calculated mode mismatch: sw single mode = %s != %s", - m_state.gpr.r[15], - actual_next_pc_is_thumb ? "Thumb" : "ARM", - sw_step_next_pc_is_thumb ? "Thumb" : "ARM"); - exit(1); - } - m_sw_single_step_next_pc = LLDB_INVALID_ADDRESS; - } -#else -#if defined (ENABLE_ARM_SINGLE_STEP) - // Are we software single stepping? - if (LLDB_BREAK_ID_IS_VALID(m_sw_single_step_break_id) || m_sw_single_step_itblock_break_count) - { - // Remove any software single stepping breakpoints that we have set - - // Do we have a normal software single step breakpoint? - if (LLDB_BREAK_ID_IS_VALID(m_sw_single_step_break_id)) - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP, "%s: removing software single step breakpoint (breakID=%d)", __FUNCTION__, m_sw_single_step_break_id); - success = m_thread.Process()->DisableBreakpoint(m_sw_single_step_break_id, true); - m_sw_single_step_break_id = LLDB_INVALID_BREAK_ID; - } - - // Do we have any Thumb IT breakpoints? - if (m_sw_single_step_itblock_break_count > 0) - { - // See if we hit one of our Thumb IT breakpoints? - DNBBreakpoint *step_bp = m_thread.Process()->Breakpoints().FindByAddress(m_state.gpr.r[15]); - - if (step_bp) - { - // We did hit our breakpoint, tell the breakpoint it was - // hit so that it can run its callback routine and fixup - // the PC. - ProcessMacOSXLog::LogIf(PD_LOG_STEP, "%s: IT software single step breakpoint hit (breakID=%u)", __FUNCTION__, step_bp->GetID()); - step_bp->BreakpointHit(m_thread.Process()->ProcessID(), m_thread.GetID()); - } - - // Remove all Thumb IT breakpoints - for (int i = 0; i < m_sw_single_step_itblock_break_count; i++) - { - if (LLDB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i])) - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP, "%s: removing IT software single step breakpoint (breakID=%d)", __FUNCTION__, m_sw_single_step_itblock_break_id[i]); - success = m_thread.Process()->DisableBreakpoint(m_sw_single_step_itblock_break_id[i], true); - m_sw_single_step_itblock_break_id[i] = LLDB_INVALID_BREAK_ID; - } - } - m_sw_single_step_itblock_break_count = 0; - - // Decode instructions up to the current PC to ensure the internal decoder state is valid for the IT block - // The decoder has to decode each instruction in the IT block even if it is not executed so that - // the fields are correctly updated - DecodeITBlockInstructions(m_state.gpr.r[15]); - } - - } - else -#endif - success = EnableHardwareSingleStep(false) == KERN_SUCCESS; -#endif - } - else - { - // The MachThread will automatically restore the suspend count - // in ShouldStop (), so we don't need to do anything here if - // we weren't the primary thread the last time - } - } - return; -} - - - -bool -MachThreadContext_arm::StepNotComplete () -{ - if (m_hw_single_chained_step_addr != LLDB_INVALID_ADDRESS) - { - kern_return_t kret = KERN_INVALID_ARGUMENT; - kret = ReadGPRRegisters(false); - if (kret == KERN_SUCCESS) - { - if (m_state.gpr.r[15] == m_hw_single_chained_step_addr) - { - //ProcessMacOSXLog::LogIf(PD_LOG_STEP, "Need to step some more at 0x%8.8x", m_hw_single_chained_step_addr); - return true; - } - } - } - - m_hw_single_chained_step_addr = LLDB_INVALID_ADDRESS; - return false; -} - - -void -MachThreadContext_arm::DecodeITBlockInstructions(lldb::addr_t curr_pc) - -{ - uint16_t opcode16; - uint32_t opcode32; - lldb::addr_t next_pc_in_itblock; - lldb::addr_t pc_in_itblock = m_last_decode_pc; - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc); - - // Decode IT block instruction from the instruction following the m_last_decoded_instruction at - // PC m_last_decode_pc upto and including the instruction at curr_pc - if (m_thread.Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2) - { - opcode32 = opcode16; - pc_in_itblock += 2; - // Check for 32 bit thumb opcode and read the upper 16 bits if needed - if (((opcode32 & 0xE000) == 0xE000) && opcode32 & 0x1800) - { - // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for - // a 32 bit Thumb opcode - // Read bits 31:16 of a 32 bit Thumb opcode - if (m_thread.Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2) - { - pc_in_itblock += 2; - // 32 bit thumb opcode - opcode32 = (opcode32 << 16) | opcode16; - } - else - { - LogError("%s: Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8lx", __FUNCTION__, pc_in_itblock); - } - } - } - else - { - LogError("%s: Error reading 16-bit Thumb instruction at pc=0x%8.8x", __FUNCTION__, pc_in_itblock); - } - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: pc_in_itblock=0x%8.8x, curr_pc=0x%8.8x", __FUNCTION__, pc_in_itblock, curr_pc); - - next_pc_in_itblock = pc_in_itblock; - while (next_pc_in_itblock <= curr_pc) - { - arm_error_t decodeError; - - m_last_decode_pc = pc_in_itblock; - decodeError = DecodeInstructionUsingDisassembler(pc_in_itblock, m_state.gpr.__cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc_in_itblock); - - pc_in_itblock = next_pc_in_itblock; - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: next_pc_in_itblock=0x%8.8x", __FUNCTION__, next_pc_in_itblock); - } -} - -#endif - -// Set the single step bit in the processor status register. -kern_return_t -MachThreadContext_arm::EnableHardwareSingleStep (bool enable) -{ - Error err; - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_STEP)); - - if (log) log->Printf("%s( enable = %d )", __FUNCTION__, enable); - - if (m_bvr0_reg == LLDB_INVALID_REGNUM || m_bcr0_reg == LLDB_INVALID_REGNUM) - return KERN_INVALID_ARGUMENT; - - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - uint32_t bvr = 0; - uint32_t bcr = 0; - - const uint32_t i = 0; - if (enable) - { - m_hw_single_chained_step_addr = LLDB_INVALID_ADDRESS; - - // Save our previous state - m_bvr0_save = reg_ctx->ReadRegisterAsUnsigned(m_bvr0_reg, 0); - m_bcr0_save = reg_ctx->ReadRegisterAsUnsigned(m_bcr0_reg, 0); - lldb::addr_t pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS); - lldb::addr_t cpsr = reg_ctx->GetFlags(0); - if (pc == LLDB_INVALID_ADDRESS) - return KERN_INVALID_ARGUMENT; - - // Set a breakpoint that will stop when the PC doesn't match the current one! - bvr = pc & 0xFFFFFFFCu; // Set the current PC as the breakpoint address - bcr = BCR_M_IMVA_MISMATCH | // Stop on address mismatch - S_USER | // Stop only in user mode - BCR_ENABLE; // Enable this breakpoint - if (cpsr & 0x20) - { - // Thumb breakpoint - if (pc & 2) - bcr |= BAS_IMVA_2_3; - else - bcr |= BAS_IMVA_0_1; - - uint16_t opcode; - Error error; - if (sizeof(opcode) == m_thread.GetProcess().ReadMemory(pc, &opcode, sizeof(opcode), error)) - { - if (((opcode & 0xE000) == 0xE000) && opcode & 0x1800) - { - // 32 bit thumb opcode... - if (pc & 2) - { - // We can't take care of a 32 bit thumb instruction single step - // with just IVA mismatching. We will need to chain an extra - // hardware single step in order to complete this single step... - m_hw_single_chained_step_addr = pc + 2; - } - else - { - // Extend the number of bits to ignore for the mismatch - bcr |= BAS_IMVA_ALL; - } - } - } - } - else - { - // ARM breakpoint - bcr |= BAS_IMVA_ALL; // Stop when any address bits change - } - - ProcessMacOSXLog::LogIf(PD_LOG_STEP, "%s: BVR%u=0x%8.8x BCR%u=0x%8.8x", __FUNCTION__, i, bvr, i, bcr); - - m_bvr0_save = reg_ctx->ReadRegisterAsUnsigned(m_bvr0_reg, 0); - m_bcr0_save = reg_ctx->ReadRegisterAsUnsigned(m_bcr0_reg, 0); - -// for (uint32_t j=i+1; j<16; ++j) -// { -// // Disable all others -// m_state.dbg.bvr[j] = 0; -// m_state.dbg.bcr[j] = 0; -// } - } - else - { - // Just restore the state we had before we did single stepping - bvr = m_bvr0_save; - bcr = m_bcr0_save; - } - - if (reg_ctx->WriteRegisterFromUnsigned(m_bvr0_reg, bvr) && - reg_ctx->WriteRegisterFromUnsigned(m_bcr0_reg, bcr)) - return KERN_SUCCESS; - - return KERN_INVALID_ARGUMENT; -} - -#if defined (ENABLE_ARM_SINGLE_STEP) - -// return 1 if bit "BIT" is set in "value" -static inline uint32_t bit(uint32_t value, uint32_t bit) -{ - return (value >> bit) & 1u; -} - -// return the bitfield "value[msbit:lsbit]". -static inline uint32_t bits(uint32_t value, uint32_t msbit, uint32_t lsbit) -{ - assert(msbit >= lsbit); - uint32_t shift_left = sizeof(value) * 8 - 1 - msbit; - value <<= shift_left; // shift anything above the msbit off of the unsigned edge - value >>= shift_left + lsbit; // shift it back again down to the lsbit (including undoing any shift from above) - return value; // return our result -} - -bool -MachThreadContext_arm::ConditionPassed(uint8_t condition, uint32_t cpsr) -{ - uint32_t cpsr_n = bit(cpsr, 31); // Negative condition code flag - uint32_t cpsr_z = bit(cpsr, 30); // Zero condition code flag - uint32_t cpsr_c = bit(cpsr, 29); // Carry condition code flag - uint32_t cpsr_v = bit(cpsr, 28); // Overflow condition code flag - - switch (condition) { - case COND_EQ: // (0x0) - if (cpsr_z == 1) return true; - break; - case COND_NE: // (0x1) - if (cpsr_z == 0) return true; - break; - case COND_CS: // (0x2) - if (cpsr_c == 1) return true; - break; - case COND_CC: // (0x3) - if (cpsr_c == 0) return true; - break; - case COND_MI: // (0x4) - if (cpsr_n == 1) return true; - break; - case COND_PL: // (0x5) - if (cpsr_n == 0) return true; - break; - case COND_VS: // (0x6) - if (cpsr_v == 1) return true; - break; - case COND_VC: // (0x7) - if (cpsr_v == 0) return true; - break; - case COND_HI: // (0x8) - if ((cpsr_c == 1) && (cpsr_z == 0)) return true; - break; - case COND_LS: // (0x9) - if ((cpsr_c == 0) || (cpsr_z == 1)) return true; - break; - case COND_GE: // (0xA) - if (cpsr_n == cpsr_v) return true; - break; - case COND_LT: // (0xB) - if (cpsr_n != cpsr_v) return true; - break; - case COND_GT: // (0xC) - if ((cpsr_z == 0) && (cpsr_n == cpsr_v)) return true; - break; - case COND_LE: // (0xD) - if ((cpsr_z == 1) || (cpsr_n != cpsr_v)) return true; - break; - default: - return true; - break; - } - - return false; -} - -bool -MachThreadContext_arm::ComputeNextPC(lldb::addr_t currentPC, arm_decoded_instruction_t decodedInstruction, bool currentPCIsThumb, lldb::addr_t *targetPC) -{ - lldb::addr_t myTargetPC, addressWherePCLives; - lldb::pid_t mypid; - - uint32_t cpsr_c = bit(m_state.gpr.cpsr, 29); // Carry condition code flag - - uint32_t firstOperand=0, secondOperand=0, shiftAmount=0, secondOperandAfterShift=0, immediateValue=0; - uint32_t halfwords=0, baseAddress=0, immediateOffset=0, addressOffsetFromRegister=0, addressOffsetFromRegisterAfterShift; - uint32_t baseAddressIndex=LLDB_INVALID_INDEX32; - uint32_t firstOperandIndex=LLDB_INVALID_INDEX32; - uint32_t secondOperandIndex=LLDB_INVALID_INDEX32; - uint32_t addressOffsetFromRegisterIndex=LLDB_INVALID_INDEX32; - uint32_t shiftRegisterIndex=LLDB_INVALID_INDEX32; - uint16_t registerList16, registerList16NoPC; - uint8_t registerList8; - uint32_t numRegistersToLoad=0; - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: instruction->code=%d", __FUNCTION__, decodedInstruction.instruction->code); - - // Get the following in this switch statement: - // - firstOperand, secondOperand, immediateValue, shiftAmount: For arithmetic, logical and move instructions - // - baseAddress, immediateOffset, shiftAmount: For LDR - // - numRegistersToLoad: For LDM and POP instructions - switch (decodedInstruction.instruction->code) - { - // Arithmetic operations that can change the PC - case ARM_INST_ADC: - case ARM_INST_ADCS: - case ARM_INST_ADD: - case ARM_INST_ADDS: - case ARM_INST_AND: - case ARM_INST_ANDS: - case ARM_INST_ASR: - case ARM_INST_ASRS: - case ARM_INST_BIC: - case ARM_INST_BICS: - case ARM_INST_EOR: - case ARM_INST_EORS: - case ARM_INST_ORR: - case ARM_INST_ORRS: - case ARM_INST_RSB: - case ARM_INST_RSBS: - case ARM_INST_RSC: - case ARM_INST_RSCS: - case ARM_INST_SBC: - case ARM_INST_SBCS: - case ARM_INST_SUB: - case ARM_INST_SUBS: - switch (decodedInstruction.addressMode) - { - case ARM_ADDR_DATA_IMM: - if (decodedInstruction.numOperands != 3) - { - LogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get firstOperand register value (at index=1) - firstOperandIndex = decodedInstruction.op[1].value; // first operand register index - firstOperand = m_state.gpr.r[firstOperandIndex]; - - // Get immediateValue (at index=2) - immediateValue = decodedInstruction.op[2].value; - - break; - - case ARM_ADDR_DATA_REG: - if (decodedInstruction.numOperands != 3) - { - LogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get firstOperand register value (at index=1) - firstOperandIndex = decodedInstruction.op[1].value; // first operand register index - firstOperand = m_state.gpr.r[firstOperandIndex]; - - // Get secondOperand register value (at index=2) - secondOperandIndex = decodedInstruction.op[2].value; // second operand register index - secondOperand = m_state.gpr.r[secondOperandIndex]; - - break; - - case ARM_ADDR_DATA_SCALED_IMM: - if (decodedInstruction.numOperands != 4) - { - LogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get firstOperand register value (at index=1) - firstOperandIndex = decodedInstruction.op[1].value; // first operand register index - firstOperand = m_state.gpr.r[firstOperandIndex]; - - // Get secondOperand register value (at index=2) - secondOperandIndex = decodedInstruction.op[2].value; // second operand register index - secondOperand = m_state.gpr.r[secondOperandIndex]; - - // Get shiftAmount as immediate value (at index=3) - shiftAmount = decodedInstruction.op[3].value; - - break; - - - case ARM_ADDR_DATA_SCALED_REG: - if (decodedInstruction.numOperands != 4) - { - LogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get firstOperand register value (at index=1) - firstOperandIndex = decodedInstruction.op[1].value; // first operand register index - firstOperand = m_state.gpr.r[firstOperandIndex]; - - // Get secondOperand register value (at index=2) - secondOperandIndex = decodedInstruction.op[2].value; // second operand register index - secondOperand = m_state.gpr.r[secondOperandIndex]; - - // Get shiftAmount from register (at index=3) - shiftRegisterIndex = decodedInstruction.op[3].value; // second operand register index - shiftAmount = m_state.gpr.r[shiftRegisterIndex]; - - break; - - case THUMB_ADDR_HR_HR: - if (decodedInstruction.numOperands != 2) - { - LogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get firstOperand register value (at index=0) - firstOperandIndex = decodedInstruction.op[0].value; // first operand register index - firstOperand = m_state.gpr.r[firstOperandIndex]; - - // Get secondOperand register value (at index=1) - secondOperandIndex = decodedInstruction.op[1].value; // second operand register index - secondOperand = m_state.gpr.r[secondOperandIndex]; - - break; - - default: - break; - } - break; - - // Logical shifts and move operations that can change the PC - case ARM_INST_LSL: - case ARM_INST_LSLS: - case ARM_INST_LSR: - case ARM_INST_LSRS: - case ARM_INST_MOV: - case ARM_INST_MOVS: - case ARM_INST_MVN: - case ARM_INST_MVNS: - case ARM_INST_ROR: - case ARM_INST_RORS: - case ARM_INST_RRX: - case ARM_INST_RRXS: - // In these cases, the firstOperand is always 0, as if it does not exist - switch (decodedInstruction.addressMode) - { - case ARM_ADDR_DATA_IMM: - if (decodedInstruction.numOperands != 2) - { - LogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get immediateValue (at index=1) - immediateValue = decodedInstruction.op[1].value; - - break; - - case ARM_ADDR_DATA_REG: - if (decodedInstruction.numOperands != 2) - { - LogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get secondOperand register value (at index=1) - secondOperandIndex = decodedInstruction.op[1].value; // second operand register index - secondOperand = m_state.gpr.r[secondOperandIndex]; - - break; - - case ARM_ADDR_DATA_SCALED_IMM: - if (decodedInstruction.numOperands != 3) - { - LogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get secondOperand register value (at index=1) - secondOperandIndex = decodedInstruction.op[2].value; // second operand register index - secondOperand = m_state.gpr.r[secondOperandIndex]; - - // Get shiftAmount as immediate value (at index=2) - shiftAmount = decodedInstruction.op[2].value; - - break; - - - case ARM_ADDR_DATA_SCALED_REG: - if (decodedInstruction.numOperands != 3) - { - LogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get secondOperand register value (at index=1) - secondOperandIndex = decodedInstruction.op[1].value; // second operand register index - secondOperand = m_state.gpr.r[secondOperandIndex]; - - // Get shiftAmount from register (at index=2) - shiftRegisterIndex = decodedInstruction.op[2].value; // second operand register index - shiftAmount = m_state.gpr.r[shiftRegisterIndex]; - - break; - - case THUMB_ADDR_HR_HR: - if (decodedInstruction.numOperands != 2) - { - LogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - if (decodedInstruction.op[0].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - - // Get secondOperand register value (at index=1) - secondOperandIndex = decodedInstruction.op[1].value; // second operand register index - secondOperand = m_state.gpr.r[secondOperandIndex]; - - break; - - default: - break; - } - - break; - - // Simple branches, used to hop around within a routine - case ARM_INST_B: - *targetPC = decodedInstruction.targetPC; // Known targetPC - return true; - break; - - // Branch-and-link, used to call ARM subroutines - case ARM_INST_BL: - *targetPC = decodedInstruction.targetPC; // Known targetPC - return true; - break; - - // Branch-and-link with exchange, used to call opposite-mode subroutines - case ARM_INST_BLX: - if ((decodedInstruction.addressMode == ARM_ADDR_BRANCH_IMM) || - (decodedInstruction.addressMode == THUMB_ADDR_UNCOND)) - { - *targetPC = decodedInstruction.targetPC; // Known targetPC - return true; - } - else // addressMode == ARM_ADDR_BRANCH_REG - { - // Unknown target unless we're branching to the PC itself, - // although this may not work properly with BLX - if (decodedInstruction.op[REG_RD].value == PC_REG) - { - // this should (almost) never happen - *targetPC = decodedInstruction.targetPC; // Known targetPC - return true; - } - - // Get the branch address and return - if (decodedInstruction.numOperands != 1) - { - LogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - // Get branch address in register (at index=0) - *targetPC = m_state.gpr.r[decodedInstruction.op[0].value]; - return true; - } - break; - - // Branch with exchange, used to hop to opposite-mode code - // Branch to Jazelle code, used to execute Java; included here since it - // acts just like BX unless the Jazelle unit is active and JPC is - // already loaded into it. - case ARM_INST_BX: - case ARM_INST_BXJ: - // Unknown target unless we're branching to the PC itself, - // although this can never switch to Thumb mode and is - // therefore pretty much useless - if (decodedInstruction.op[REG_RD].value == PC_REG) - { - // this should (almost) never happen - *targetPC = decodedInstruction.targetPC; // Known targetPC - return true; - } - - // Get the branch address and return - if (decodedInstruction.numOperands != 1) - { - LogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - // Get branch address in register (at index=0) - *targetPC = m_state.gpr.r[decodedInstruction.op[0].value]; - return true; - break; - - // Compare and branch on zero/non-zero (Thumb-16 only) - // Unusual condition check built into the instruction - case ARM_INST_CBZ: - case ARM_INST_CBNZ: - // Branch address is known at compile time - // Get the branch address and return - if (decodedInstruction.numOperands != 2) - { - LogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - // Get branch address as an immediate value (at index=1) - *targetPC = decodedInstruction.op[1].value; - return true; - break; - - // Load register can be used to load PC, usually with a function pointer - case ARM_INST_LDR: - if (decodedInstruction.op[REG_RD].value != PC_REG) - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - switch (decodedInstruction.addressMode) - { - case ARM_ADDR_LSWUB_IMM: - case ARM_ADDR_LSWUB_IMM_PRE: - case ARM_ADDR_LSWUB_IMM_POST: - if (decodedInstruction.numOperands != 3) - { - LogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - // Get baseAddress from register (at index=1) - baseAddressIndex = decodedInstruction.op[1].value; - baseAddress = m_state.gpr.r[baseAddressIndex]; - - // Get immediateOffset (at index=2) - immediateOffset = decodedInstruction.op[2].value; - break; - - case ARM_ADDR_LSWUB_REG: - case ARM_ADDR_LSWUB_REG_PRE: - case ARM_ADDR_LSWUB_REG_POST: - if (decodedInstruction.numOperands != 3) - { - LogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - // Get baseAddress from register (at index=1) - baseAddressIndex = decodedInstruction.op[1].value; - baseAddress = m_state.gpr.r[baseAddressIndex]; - - // Get immediateOffset from register (at index=2) - addressOffsetFromRegisterIndex = decodedInstruction.op[2].value; - addressOffsetFromRegister = m_state.gpr.r[addressOffsetFromRegisterIndex]; - - break; - - case ARM_ADDR_LSWUB_SCALED: - case ARM_ADDR_LSWUB_SCALED_PRE: - case ARM_ADDR_LSWUB_SCALED_POST: - if (decodedInstruction.numOperands != 4) - { - LogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - // Get baseAddress from register (at index=1) - baseAddressIndex = decodedInstruction.op[1].value; - baseAddress = m_state.gpr.r[baseAddressIndex]; - - // Get immediateOffset from register (at index=2) - addressOffsetFromRegisterIndex = decodedInstruction.op[2].value; - addressOffsetFromRegister = m_state.gpr.r[addressOffsetFromRegisterIndex]; - - // Get shiftAmount (at index=3) - shiftAmount = decodedInstruction.op[3].value; - - break; - - default: - break; - } - break; - - // 32b load multiple operations can load the PC along with everything else, - // usually to return from a function call - case ARM_INST_LDMDA: - case ARM_INST_LDMDB: - case ARM_INST_LDMIA: - case ARM_INST_LDMIB: - if (decodedInstruction.op[LDM_REGLIST].value & PC_REGLIST_BIT) - { - if (decodedInstruction.numOperands != 2) - { - LogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); - return false; - } - - // Get baseAddress from register (at index=0) - baseAddressIndex = decodedInstruction.op[0].value; - baseAddress = m_state.gpr.r[baseAddressIndex]; - - // Get registerList from register (at index=1) - registerList16 = (uint16_t)decodedInstruction.op[1].value; - - // Count number of registers to load in the multiple register list excluding the PC - registerList16NoPC = registerList16&0x3FFF; // exclude the PC - numRegistersToLoad=0; - for (int i = 0; i < 16; i++) - { - if (registerList16NoPC & 0x1) numRegistersToLoad++; - registerList16NoPC = registerList16NoPC >> 1; - } - } - else - { - LogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); - return false; - } - break; - - // Normal 16-bit LD multiple can't touch R15, but POP can - case ARM_INST_POP: // Can also get the PC & updates SP - // Get baseAddress from SP (at index=0) - baseAddress = m_state.gpr.__sp; - - if (decodedInstruction.thumb16b) - { - // Get registerList from register (at index=0) - registerList8 = (uint8_t)decodedInstruction.op[0].value; - - // Count number of registers to load in the multiple register list - numRegistersToLoad=0; - for (int i = 0; i < 8; i++) - { - if (registerList8 & 0x1) numRegistersToLoad++; - registerList8 = registerList8 >> 1; - } - } - else - { - // Get registerList from register (at index=0) - registerList16 = (uint16_t)decodedInstruction.op[0].value; - - // Count number of registers to load in the multiple register list excluding the PC - registerList16NoPC = registerList16&0x3FFF; // exclude the PC - numRegistersToLoad=0; - for (int i = 0; i < 16; i++) - { - if (registerList16NoPC & 0x1) numRegistersToLoad++; - registerList16NoPC = registerList16NoPC >> 1; - } - } - break; - - // 16b TBB and TBH instructions load a jump address from a table - case ARM_INST_TBB: - case ARM_INST_TBH: - // Get baseAddress from register (at index=0) - baseAddressIndex = decodedInstruction.op[0].value; - baseAddress = m_state.gpr.r[baseAddressIndex]; - - // Get immediateOffset from register (at index=1) - addressOffsetFromRegisterIndex = decodedInstruction.op[1].value; - addressOffsetFromRegister = m_state.gpr.r[addressOffsetFromRegisterIndex]; - break; - - // ThumbEE branch-to-handler instructions: Jump to handlers at some offset - // from a special base pointer register (which is unknown at disassembly time) - case ARM_INST_HB: - case ARM_INST_HBP: -// TODO: ARM_INST_HB, ARM_INST_HBP - break; - - case ARM_INST_HBL: - case ARM_INST_HBLP: -// TODO: ARM_INST_HBL, ARM_INST_HBLP - break; - - // Breakpoint and software interrupt jump to interrupt handler (always ARM) - case ARM_INST_BKPT: - case ARM_INST_SMC: - case ARM_INST_SVC: - - // Return from exception, obviously modifies PC [interrupt only!] - case ARM_INST_RFEDA: - case ARM_INST_RFEDB: - case ARM_INST_RFEIA: - case ARM_INST_RFEIB: - - // Other instructions either can't change R15 or are "undefined" if you do, - // so no sane compiler should ever generate them & we don't care here. - // Also, R15 can only legally be used in a read-only manner for the - // various ARM addressing mode (to get PC-relative addressing of constants), - // but can NOT be used with any of the update modes. - default: - LogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code); - return false; - break; - } - - // Adjust PC if PC is one of the input operands - if (baseAddressIndex == PC_REG) - { - if (currentPCIsThumb) - baseAddress += 4; - else - baseAddress += 8; - } - - if (firstOperandIndex == PC_REG) - { - if (currentPCIsThumb) - firstOperand += 4; - else - firstOperand += 8; - } - - if (secondOperandIndex == PC_REG) - { - if (currentPCIsThumb) - secondOperand += 4; - else - secondOperand += 8; - } - - if (addressOffsetFromRegisterIndex == PC_REG) - { - if (currentPCIsThumb) - addressOffsetFromRegister += 4; - else - addressOffsetFromRegister += 8; - } - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, - "%s: firstOperand=%8.8x, secondOperand=%8.8x, immediateValue = %d, shiftAmount = %d, baseAddress = %8.8x, addressOffsetFromRegister = %8.8x, immediateOffset = %d, numRegistersToLoad = %d", - __FUNCTION__, - firstOperand, - secondOperand, - immediateValue, - shiftAmount, - baseAddress, - addressOffsetFromRegister, - immediateOffset, - numRegistersToLoad); - - - // Calculate following values after applying shiftAmount: - // - immediateOffsetAfterShift, secondOperandAfterShift - - switch (decodedInstruction.scaleMode) - { - case ARM_SCALE_NONE: - addressOffsetFromRegisterAfterShift = addressOffsetFromRegister; - secondOperandAfterShift = secondOperand; - break; - - case ARM_SCALE_LSL: // Logical shift left - addressOffsetFromRegisterAfterShift = addressOffsetFromRegister << shiftAmount; - secondOperandAfterShift = secondOperand << shiftAmount; - break; - - case ARM_SCALE_LSR: // Logical shift right - addressOffsetFromRegisterAfterShift = addressOffsetFromRegister >> shiftAmount; - secondOperandAfterShift = secondOperand >> shiftAmount; - break; - - case ARM_SCALE_ASR: // Arithmetic shift right - asm("mov %0, %1, asr %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount)); - asm("mov %0, %1, asr %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount)); - break; - - case ARM_SCALE_ROR: // Rotate right - asm("mov %0, %1, ror %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount)); - asm("mov %0, %1, ror %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount)); - break; - - case ARM_SCALE_RRX: // Rotate right, pulling in carry (1-bit shift only) - asm("mov %0, %1, rrx" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister)); - asm("mov %0, %1, rrx" : "=r" (secondOperandAfterShift) : "r" (secondOperand)); - break; - } - - // Emulate instruction to calculate targetPC - // All branches are already handled in the first switch statement. A branch should not reach this switch - switch (decodedInstruction.instruction->code) - { - // Arithmetic operations that can change the PC - case ARM_INST_ADC: - case ARM_INST_ADCS: - // Add with Carry - *targetPC = firstOperand + (secondOperandAfterShift + immediateValue) + cpsr_c; - break; - - case ARM_INST_ADD: - case ARM_INST_ADDS: - *targetPC = firstOperand + (secondOperandAfterShift + immediateValue); - break; - - case ARM_INST_AND: - case ARM_INST_ANDS: - *targetPC = firstOperand & (secondOperandAfterShift + immediateValue); - break; - - case ARM_INST_ASR: - case ARM_INST_ASRS: - asm("mov %0, %1, asr %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); - *targetPC = myTargetPC; - break; - - case ARM_INST_BIC: - case ARM_INST_BICS: - asm("bic %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); - *targetPC = myTargetPC; - break; - - case ARM_INST_EOR: - case ARM_INST_EORS: - asm("eor %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); - *targetPC = myTargetPC; - break; - - case ARM_INST_ORR: - case ARM_INST_ORRS: - asm("orr %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); - *targetPC = myTargetPC; - break; - - case ARM_INST_RSB: - case ARM_INST_RSBS: - asm("rsb %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); - *targetPC = myTargetPC; - break; - - case ARM_INST_RSC: - case ARM_INST_RSCS: - myTargetPC = secondOperandAfterShift - (firstOperand + !cpsr_c); - *targetPC = myTargetPC; - break; - - case ARM_INST_SBC: - case ARM_INST_SBCS: - asm("sbc %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue + !cpsr_c)); - *targetPC = myTargetPC; - break; - - case ARM_INST_SUB: - case ARM_INST_SUBS: - asm("sub %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); - *targetPC = myTargetPC; - break; - - // Logical shifts and move operations that can change the PC - case ARM_INST_LSL: - case ARM_INST_LSLS: - case ARM_INST_LSR: - case ARM_INST_LSRS: - case ARM_INST_MOV: - case ARM_INST_MOVS: - case ARM_INST_ROR: - case ARM_INST_RORS: - case ARM_INST_RRX: - case ARM_INST_RRXS: - myTargetPC = secondOperandAfterShift + immediateValue; - *targetPC = myTargetPC; - break; - - case ARM_INST_MVN: - case ARM_INST_MVNS: - myTargetPC = !(secondOperandAfterShift + immediateValue); - *targetPC = myTargetPC; - break; - - // Load register can be used to load PC, usually with a function pointer - case ARM_INST_LDR: - switch (decodedInstruction.addressMode) { - case ARM_ADDR_LSWUB_IMM_POST: - case ARM_ADDR_LSWUB_REG_POST: - case ARM_ADDR_LSWUB_SCALED_POST: - addressWherePCLives = baseAddress; - break; - - case ARM_ADDR_LSWUB_IMM: - case ARM_ADDR_LSWUB_REG: - case ARM_ADDR_LSWUB_SCALED: - case ARM_ADDR_LSWUB_IMM_PRE: - case ARM_ADDR_LSWUB_REG_PRE: - case ARM_ADDR_LSWUB_SCALED_PRE: - addressWherePCLives = baseAddress + (addressOffsetFromRegisterAfterShift + immediateOffset); - break; - - default: - break; - } - - mypid = m_thread.ProcessID(); - if (PDProcessMemoryRead(mypid, addressWherePCLives, sizeof(lldb::addr_t), &myTargetPC) != sizeof(lldb::addr_t)) - { - LogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); - return false; - } - - *targetPC = myTargetPC; - break; - - // 32b load multiple operations can load the PC along with everything else, - // usually to return from a function call - case ARM_INST_LDMDA: - mypid = m_thread.ProcessID(); - addressWherePCLives = baseAddress; - if (PDProcessMemoryRead(mypid, addressWherePCLives, sizeof(lldb::addr_t), &myTargetPC) != sizeof(lldb::addr_t)) - { - LogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); - return false; - } - - *targetPC = myTargetPC; - break; - - case ARM_INST_LDMDB: - mypid = m_thread.ProcessID(); - addressWherePCLives = baseAddress - 4; - if (PDProcessMemoryRead(mypid, addressWherePCLives, sizeof(lldb::addr_t), &myTargetPC) != sizeof(lldb::addr_t)) - { - LogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); - return false; - } - - *targetPC = myTargetPC; - break; - - case ARM_INST_LDMIB: - mypid = m_thread.ProcessID(); - addressWherePCLives = baseAddress + numRegistersToLoad*4 + 4; - if (PDProcessMemoryRead(mypid, addressWherePCLives, sizeof(lldb::addr_t), &myTargetPC) != sizeof(lldb::addr_t)) - { - LogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); - return false; - } - - *targetPC = myTargetPC; - break; - - case ARM_INST_LDMIA: // same as pop - // Normal 16-bit LD multiple can't touch R15, but POP can - case ARM_INST_POP: // Can also get the PC & updates SP - mypid = m_thread.ProcessID(); - addressWherePCLives = baseAddress + numRegistersToLoad*4; - if (PDProcessMemoryRead(mypid, addressWherePCLives, sizeof(lldb::addr_t), &myTargetPC) != sizeof(lldb::addr_t)) - { - LogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); - return false; - } - - *targetPC = myTargetPC; - break; - - // 16b TBB and TBH instructions load a jump address from a table - case ARM_INST_TBB: - mypid = m_thread.ProcessID(); - addressWherePCLives = baseAddress + addressOffsetFromRegisterAfterShift; - if (PDProcessMemoryRead(mypid, addressWherePCLives, 1, &halfwords) != 1) - { - LogError("Could not read memory at %8.8x to get targetPC when processing the TBB instruction!", addressWherePCLives); - return false; - } - // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords - *targetPC = (currentPC + 4) + 2*halfwords; - break; - - case ARM_INST_TBH: - mypid = m_thread.ProcessID(); - addressWherePCLives = ((baseAddress + (addressOffsetFromRegisterAfterShift << 1)) & ~0x1); - if (PDProcessMemoryRead(mypid, addressWherePCLives, 2, &halfwords) != 2) - { - LogError("Could not read memory at %8.8x to get targetPC when processing the TBH instruction!", addressWherePCLives); - return false; - } - // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords - *targetPC = (currentPC + 4) + 2*halfwords; - break; - - // ThumbEE branch-to-handler instructions: Jump to handlers at some offset - // from a special base pointer register (which is unknown at disassembly time) - case ARM_INST_HB: - case ARM_INST_HBP: - // TODO: ARM_INST_HB, ARM_INST_HBP - break; - - case ARM_INST_HBL: - case ARM_INST_HBLP: - // TODO: ARM_INST_HBL, ARM_INST_HBLP - break; - - // Breakpoint and software interrupt jump to interrupt handler (always ARM) - case ARM_INST_BKPT: - case ARM_INST_SMC: - case ARM_INST_SVC: - // TODO: ARM_INST_BKPT, ARM_INST_SMC, ARM_INST_SVC - break; - - // Return from exception, obviously modifies PC [interrupt only!] - case ARM_INST_RFEDA: - case ARM_INST_RFEDB: - case ARM_INST_RFEIA: - case ARM_INST_RFEIB: - // TODO: ARM_INST_RFEDA, ARM_INST_RFEDB, ARM_INST_RFEIA, ARM_INST_RFEIB - break; - - // Other instructions either can't change R15 or are "undefined" if you do, - // so no sane compiler should ever generate them & we don't care here. - // Also, R15 can only legally be used in a read-only manner for the - // various ARM addressing mode (to get PC-relative addressing of constants), - // but can NOT be used with any of the update modes. - default: - LogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code); - return false; - break; - } - - return true; -} - -void -MachThreadContext_arm::EvaluateNextInstructionForSoftwareBreakpointSetup(lldb::addr_t currentPC, uint32_t cpsr, bool currentPCIsThumb, lldb::addr_t *nextPC, bool *nextPCIsThumb) -{ - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "MachThreadContext_arm::EvaluateNextInstructionForSoftwareBreakpointSetup() called"); - - lldb::addr_t targetPC = LLDB_INVALID_ADDRESS; - uint32_t registerValue; - arm_error_t decodeError; - lldb::addr_t currentPCInITBlock, nextPCInITBlock; - int i; - bool last_decoded_instruction_executes = true; - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: default nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM"); - - // Update *nextPC and *nextPCIsThumb for special cases - if (m_last_decode_thumb.itBlockRemaining) // we are in an IT block - { - // Set the nextPC to the PC of the instruction which will execute in the IT block - // If none of the instruction execute in the IT block based on the condition flags, - // then point to the instruction immediately following the IT block - const int itBlockRemaining = m_last_decode_thumb.itBlockRemaining; - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: itBlockRemaining=%8.8x", __FUNCTION__, itBlockRemaining); - - // Determine the PC at which the next instruction resides - if (m_last_decode_arm.thumb16b) - currentPCInITBlock = currentPC + 2; - else - currentPCInITBlock = currentPC + 4; - - for (i = 0; i < itBlockRemaining; i++) - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: currentPCInITBlock=%8.8x", __FUNCTION__, currentPCInITBlock); - decodeError = DecodeInstructionUsingDisassembler(currentPCInITBlock, cpsr, &m_last_decode_arm, &m_last_decode_thumb, &nextPCInITBlock); - - if (decodeError != ARM_SUCCESS) - LogError("unable to disassemble instruction at 0x%8.8lx", currentPCInITBlock); - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: condition=%d", __FUNCTION__, m_last_decode_arm.condition); - if (ConditionPassed(m_last_decode_arm.condition, cpsr)) - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: Condition codes matched for instruction %d", __FUNCTION__, i); - break; // break from the for loop - } - else - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: Condition codes DID NOT matched for instruction %d", __FUNCTION__, i); - } - - // update currentPC and nextPCInITBlock - currentPCInITBlock = nextPCInITBlock; - } - - if (i == itBlockRemaining) // We came out of the IT block without executing any instructions - last_decoded_instruction_executes = false; - - *nextPC = currentPCInITBlock; - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: After IT block step-through: *nextPC=%8.8x", __FUNCTION__, *nextPC); - } - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, - "%s: cpsr = %8.8x, thumb16b = %d, thumb = %d, branch = %d, conditional = %d, knownTarget = %d, links = %d, canSwitchMode = %d, doesSwitchMode = %d", - __FUNCTION__, - cpsr, - m_last_decode_arm.thumb16b, - m_last_decode_arm.thumb, - m_last_decode_arm.branch, - m_last_decode_arm.conditional, - m_last_decode_arm.knownTarget, - m_last_decode_arm.links, - m_last_decode_arm.canSwitchMode, - m_last_decode_arm.doesSwitchMode); - - - if (last_decoded_instruction_executes && // Was this a conditional instruction that did execute? - m_last_decode_arm.branch && // Can this instruction change the PC? - (m_last_decode_arm.instruction->code != ARM_INST_SVC)) // If this instruction is not an SVC instruction - { - // Set targetPC. Compute if needed. - if (m_last_decode_arm.knownTarget) - { - // Fixed, known PC-relative - targetPC = m_last_decode_arm.targetPC; - } - else - { - // if targetPC is not known at compile time (PC-relative target), compute targetPC - if (!ComputeNextPC(currentPC, m_last_decode_arm, currentPCIsThumb, &targetPC)) - { - LogError("%s: Unable to compute targetPC for instruction at 0x%8.8lx", __FUNCTION__, currentPC); - targetPC = LLDB_INVALID_ADDRESS; - } - } - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: targetPC=0x%8.8x, cpsr=0x%8.8x, condition=0x%hhx", __FUNCTION__, targetPC, cpsr, m_last_decode_arm.condition); - - // Refine nextPC computation - if ((m_last_decode_arm.instruction->code == ARM_INST_CBZ) || - (m_last_decode_arm.instruction->code == ARM_INST_CBNZ)) - { - // Compare and branch on zero/non-zero (Thumb-16 only) - // Unusual condition check built into the instruction - registerValue = m_state.gpr.r[m_last_decode_arm.op[REG_RD].value]; - - if (m_last_decode_arm.instruction->code == ARM_INST_CBZ) - { - if (registerValue == 0) - *nextPC = targetPC; - } - else - { - if (registerValue != 0) - *nextPC = targetPC; - } - } - else if (m_last_decode_arm.conditional) // Is the change conditional on flag results? - { - if (ConditionPassed(m_last_decode_arm.condition, cpsr)) // conditions match - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: Condition matched!", __FUNCTION__); - *nextPC = targetPC; - } - else - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: Condition did not match!", __FUNCTION__); - } - } - else - { - *nextPC = targetPC; - } - - // Refine nextPCIsThumb computation - if (m_last_decode_arm.doesSwitchMode) - { - *nextPCIsThumb = !currentPCIsThumb; - } - else if (m_last_decode_arm.canSwitchMode) - { - // Legal to switch ARM <--> Thumb mode with this branch - // dependent on bit[0] of targetPC - *nextPCIsThumb = (*nextPC & 1u) != 0; - } - else - { - *nextPCIsThumb = currentPCIsThumb; - } - } - - ProcessMacOSXLog::LogIf(PD_LOG_STEP, "%s: calculated nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM"); -} - - -arm_error_t -MachThreadContext_arm::DecodeInstructionUsingDisassembler(lldb::addr_t curr_pc, uint32_t curr_cpsr, arm_decoded_instruction_t *decodedInstruction, thumb_static_data_t *thumbStaticData, lldb::addr_t *next_pc) -{ - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: pc=0x%8.8x, cpsr=0x%8.8x", __FUNCTION__, curr_pc, curr_cpsr); - - const uint32_t isetstate_mask = MASK_CPSR_T | MASK_CPSR_J; - const uint32_t curr_isetstate = curr_cpsr & isetstate_mask; - uint32_t opcode32; - lldb::addr_t nextPC = curr_pc; - arm_error_t decodeReturnCode = ARM_SUCCESS; - - m_last_decode_pc = curr_pc; - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc); - - switch (curr_isetstate) { - case 0x0: // ARM Instruction - // Read the ARM opcode - if (m_thread.Process()->Task().ReadMemory(curr_pc, 4, &opcode32) != 4) - { - LogError("unable to read opcode bits 31:0 for an ARM opcode at 0x%8.8lx", curr_pc); - decodeReturnCode = ARM_ERROR; - } - else - { - nextPC += 4; - decodeReturnCode = ArmDisassembler((uint64_t)curr_pc, opcode32, false, decodedInstruction, NULL, 0, NULL, 0); - - if (decodeReturnCode != ARM_SUCCESS) - LogError("Unable to decode ARM instruction 0x%8.8x at 0x%8.8lx", opcode32, curr_pc); - } - break; - - case 0x20: // Thumb Instruction - uint16_t opcode16; - // Read the a 16 bit Thumb opcode - if (m_thread.Process()->Task().ReadMemory(curr_pc, 2, &opcode16) != 2) - { - LogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8lx", curr_pc); - decodeReturnCode = ARM_ERROR; - } - else - { - nextPC += 2; - opcode32 = opcode16; - - decodeReturnCode = ThumbDisassembler((uint64_t)curr_pc, opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0); - - switch (decodeReturnCode) { - case ARM_SKIP: - // 32 bit thumb opcode - nextPC += 2; - if (m_thread.Process()->Task().ReadMemory(curr_pc+2, 2, &opcode16) != 2) - { - LogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8lx", curr_pc+2); - } - else - { - opcode32 = (opcode32 << 16) | opcode16; - - decodeReturnCode = ThumbDisassembler((uint64_t)(curr_pc+2), opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0); - - if (decodeReturnCode != ARM_SUCCESS) - LogError("Unable to decode 2nd half of Thumb instruction 0x%8.4hx at 0x%8.8lx", opcode16, curr_pc+2); - break; - } - break; - - case ARM_SUCCESS: - // 16 bit thumb opcode; at this point we are done decoding the opcode - break; - - default: - LogError("Unable to decode Thumb instruction 0x%8.4hx at 0x%8.8lx", opcode16, curr_pc); - decodeReturnCode = ARM_ERROR; - break; - } - } - break; - - default: - break; - } - - if (next_pc) - *next_pc = nextPC; - - return decodeReturnCode; -} - -bool -MachThreadContext_arm::BreakpointHit(lldb::pid_t pid, lldb::tid_t tid, lldb::user_id_t breakID, void *baton) -{ - lldb::addr_t bkpt_pc = (lldb::addr_t)baton; - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s(pid = %i, tid = %4.4x, breakID = %u, baton = %p): Setting PC to 0x%8.8x", __FUNCTION__, pid, tid, breakID, baton, bkpt_pc); - return PDThreadSetRegisterValueByID(pid, tid, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, bkpt_pc); -} - -// Set the single step bit in the processor status register. -kern_return_t -MachThreadContext_arm::SetSingleStepSoftwareBreakpoints() -{ - Error err; - err = ReadGPRRegisters(false); - - if (err.Fail()) - { - err.Log("%s: failed to read the GPR registers", __FUNCTION__); - return err.GetError(); - } - - lldb::addr_t curr_pc = m_state.gpr.r[15]; - uint32_t curr_cpsr = m_state.gpr.__cpsr; - lldb::addr_t next_pc = curr_pc; - - bool curr_pc_is_thumb = (m_state.gpr.__cpsr & 0x20) != 0; - bool next_pc_is_thumb = curr_pc_is_thumb; - - uint32_t curr_itstate = ((curr_cpsr & 0x6000000) >> 25) | ((curr_cpsr & 0xFC00) >> 8); - bool inITBlock = (curr_itstate & 0xF) ? 1 : 0; - bool lastInITBlock = ((curr_itstate & 0xF) == 0x8) ? 1 : 0; - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: curr_pc=0x%8.8x (%s), curr_itstate=0x%x, inITBlock=%d, lastInITBlock=%d", __FUNCTION__, curr_pc, curr_pc_is_thumb ? "Thumb" : "ARM", curr_itstate, inITBlock, lastInITBlock); - - // If the instruction is not in the IT block, then decode using the Disassembler and compute next_pc - if (!inITBlock) - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: Decoding an instruction NOT in the IT block", __FUNCTION__); - - arm_error_t decodeReturnCode = DecodeInstructionUsingDisassembler(curr_pc, curr_cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc); - - if (decodeReturnCode != ARM_SUCCESS) - { - err = KERN_INVALID_ARGUMENT; - LogError("MachThreadContext_arm::SetSingleStepSoftwareBreakpoints: Unable to disassemble instruction at 0x%8.8lx", curr_pc); - } - } - else - { - next_pc = curr_pc + ((m_last_decode_arm.thumb16b) ? 2 : 4); - } - - // Instruction is NOT in the IT block OR - if (!inITBlock) - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: normal instruction", __FUNCTION__); - EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb); - } - else if (inITBlock && !m_last_decode_arm.setsFlags) - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: IT instruction that doesn't set flags", __FUNCTION__); - EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb); - } - else if (lastInITBlock && m_last_decode_arm.branch) - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: IT instruction which last in the IT block and is a branch", __FUNCTION__); - EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb); - } - else - { - // Instruction is in IT block and can modify the CPSR flags - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: IT instruction that sets flags", __FUNCTION__); - - // NOTE: When this point of code is reached, the instruction at curr_pc has already been decoded - // inside the function ShouldStop (). Therefore m_last_decode_arm, m_last_decode_thumb - // reflect the decoded instruction at curr_pc - - // If we find an instruction inside the IT block which will set/modify the condition flags (NZCV bits in CPSR), - // we set breakpoints at all remaining instructions inside the IT block starting from the instruction immediately - // following this one AND a breakpoint at the instruction immediately following the IT block. We do this because - // we cannot determine the next_pc until the instruction at which we are currently stopped executes. Hence we - // insert (m_last_decode_thumb.itBlockRemaining+1) 16-bit Thumb breakpoints at consecutive memory locations - // starting at addrOfNextInstructionInITBlock. We record these breakpoints in class variable m_sw_single_step_itblock_break_id[], - // and also record the total number of IT breakpoints set in the variable 'm_sw_single_step_itblock_break_count'. - - // The instructions inside the IT block, which are replaced by the 16-bit Thumb breakpoints (opcode=0xDEFE) - // instructions, can be either Thumb-16 or Thumb-32. When a Thumb-32 instruction (say, inst#1) is replaced Thumb - // by a 16-bit breakpoint (OS only supports 16-bit breakpoints in Thumb mode and 32-bit breakpoints in ARM mode), the - // breakpoint for the next instruction (say instr#2) is saved in the upper half of this Thumb-32 (instr#1) - // instruction. Hence if the execution stops at Breakpoint2 corresponding to instr#2, the PC is offset by 16-bits. - // We therefore have to keep track of PC of each instruction in the IT block that is being replaced with the 16-bit - // Thumb breakpoint, to ensure that when the breakpoint is hit, the PC is adjusted to the correct value. We save - // the actual PC corresponding to each instruction in the IT block by associating a call back with each breakpoint - // we set and passing it as a baton. When the breakpoint hits and the callback routine is called, the routine - // adjusts the PC based on the baton that is passed to it. - - lldb::addr_t addrOfNextInstructionInITBlock, pcInITBlock, nextPCInITBlock, bpAddressInITBlock; - uint16_t opcode16; - uint32_t opcode32; - - addrOfNextInstructionInITBlock = (m_last_decode_arm.thumb16b) ? curr_pc + 2 : curr_pc + 4; - - pcInITBlock = addrOfNextInstructionInITBlock; - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: itBlockRemaining=%d", __FUNCTION__, m_last_decode_thumb.itBlockRemaining); - - m_sw_single_step_itblock_break_count = 0; - for (int i = 0; i <= m_last_decode_thumb.itBlockRemaining; i++) - { - if (LLDB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i])) - { - LogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Array m_sw_single_step_itblock_break_id should not contain any valid breakpoint IDs at this point. But found a valid breakID=%d at index=%d", m_sw_single_step_itblock_break_id[i], i); - } - else - { - nextPCInITBlock = pcInITBlock; - // Compute nextPCInITBlock based on opcode present at pcInITBlock - if (m_thread.Process()->Task().ReadMemory(pcInITBlock, 2, &opcode16) == 2) - { - opcode32 = opcode16; - nextPCInITBlock += 2; - - // Check for 32 bit thumb opcode and read the upper 16 bits if needed - if (((opcode32 & 0xE000) == 0xE000) && (opcode32 & 0x1800)) - { - // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for - // a 32 bit Thumb opcode - // Read bits 31:16 of a 32 bit Thumb opcode - if (m_thread.Process()->Task().ReadMemory(pcInITBlock+2, 2, &opcode16) == 2) - { - // 32 bit thumb opcode - opcode32 = (opcode32 << 16) | opcode16; - nextPCInITBlock += 2; - } - else - { - LogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8lx", nextPCInITBlock); - } - } - } - else - { - LogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Error reading 16-bit Thumb instruction at pc=0x%8.8x", nextPCInITBlock); - } - - - // Set breakpoint and associate a callback function with it - bpAddressInITBlock = addrOfNextInstructionInITBlock + 2*i; - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: Setting IT breakpoint[%d] at address: 0x%8.8x", __FUNCTION__, i, bpAddressInITBlock); - - m_sw_single_step_itblock_break_id[i] = m_thread.Process()->CreateBreakpoint(bpAddressInITBlock, 2, false, m_thread.GetID()); - if (!LLDB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i])) - err = KERN_INVALID_ARGUMENT; - else - { - ProcessMacOSXLog::LogIf(PD_LOG_STEP, "%s: Set IT breakpoint[%i]=%d set at 0x%8.8x for instruction at 0x%8.8x", __FUNCTION__, i, m_sw_single_step_itblock_break_id[i], bpAddressInITBlock, pcInITBlock); - - // Set the breakpoint callback for these special IT breakpoints - // so that if one of these breakpoints gets hit, it knows to - // update the PC to the original address of the conditional - // IT instruction. - PDBreakpointSetCallback(m_thread.ProcessID(), m_sw_single_step_itblock_break_id[i], MachThreadContext_arm::BreakpointHit, (void*)pcInITBlock); - m_sw_single_step_itblock_break_count++; - } - } - - pcInITBlock = nextPCInITBlock; - } - - ProcessMacOSXLog::LogIf(PD_LOG_STEP | PD_LOG_VERBOSE, "%s: Set %u IT software single breakpoints.", __FUNCTION__, m_sw_single_step_itblock_break_count); - - } - - ProcessMacOSXLog::LogIf(PD_LOG_STEP, "%s: next_pc=0x%8.8x (%s)", __FUNCTION__, next_pc, next_pc_is_thumb ? "Thumb" : "ARM"); - - if (next_pc & 0x1) - { - assert(next_pc_is_thumb); - } - - if (next_pc_is_thumb) - { - next_pc &= ~0x1; - } - else - { - assert((next_pc & 0x3) == 0); - } - - if (!inITBlock || (inITBlock && !m_last_decode_arm.setsFlags) || (lastInITBlock && m_last_decode_arm.branch)) - { - err = KERN_SUCCESS; - -#if defined DNB_ARCH_MACH_ARM_DEBUG_SW_STEP - m_sw_single_step_next_pc = next_pc; - if (next_pc_is_thumb) - m_sw_single_step_next_pc |= 1; // Set bit zero if the next PC is expected to be Thumb -#else - const DNBBreakpoint *bp = m_thread.Process()->Breakpoints().FindByAddress(next_pc); - - if (bp == NULL) - { - m_sw_single_step_break_id = m_thread.Process()->CreateBreakpoint(next_pc, next_pc_is_thumb ? 2 : 4, false, m_thread.GetID()); - if (!LLDB_BREAK_ID_IS_VALID(m_sw_single_step_break_id)) - err = KERN_INVALID_ARGUMENT; - ProcessMacOSXLog::LogIf(PD_LOG_STEP, "%s: software single step breakpoint with breakID=%d set at 0x%8.8x", __FUNCTION__, m_sw_single_step_break_id, next_pc); - } -#endif - } - - return err.GetError(); -} - -#endif - -MachThreadContext* -MachThreadContext_arm::Create (const ArchSpec &arch_spec, ThreadMacOSX &thread) -{ - return new MachThreadContext_arm(thread); -} - -void -MachThreadContext_arm::Initialize() -{ - ArchSpec arch_spec(eArchTypeMachO, 12, UINT32_MAX); - ProcessMacOSX::AddArchCreateCallback(arch_spec, MachThreadContext_arm::Create); -} diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_arm.h b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_arm.h deleted file mode 100644 index 14984c9f9eb..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_arm.h +++ /dev/null @@ -1,60 +0,0 @@ -//===-- MachThreadContext_arm.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_MachThreadContext_arm_h_ -#define liblldb_MachThreadContext_arm_h_ - -#include "MachThreadContext.h" -#include "RegisterContextMach_arm.h" - -class ThreadMacOSX; - -class MachThreadContext_arm : public MachThreadContext -{ -public: - enum { kMaxNumThumbITBreakpoints = 4 }; - - static MachThreadContext* - Create (const lldb_private::ArchSpec &arch_spec, ThreadMacOSX &thread); - - static void - Initialize(); - - MachThreadContext_arm(ThreadMacOSX &thread); - - virtual - ~MachThreadContext_arm(); - - virtual lldb::RegisterContextSP - CreateRegisterContext (lldb_private::StackFrame *frame) const; - - virtual void - InitializeInstance(); - - virtual void - ThreadWillResume (); - - virtual bool - ShouldStop (); - - virtual void - RefreshStateAfterStop (); - -protected: - kern_return_t - EnableHardwareSingleStep (bool enable); - -protected: - lldb::addr_t m_hw_single_chained_step_addr; - uint32_t m_bvr0_reg; - uint32_t m_bcr0_reg; - uint32_t m_bvr0_save; - uint32_t m_bcr0_save; -}; -#endif // #ifndef liblldb_MachThreadContext_arm_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.cpp deleted file mode 100644 index 5141e4b67eb..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.cpp +++ /dev/null @@ -1,243 +0,0 @@ -//===-- MachThreadContext_i386.cpp ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#if defined (__i386__) || defined (__x86_64__) - - -#include "MachThreadContext_i386.h" - -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/Symbol.h" - -#include "ProcessMacOSX.h" -#include "ThreadMacOSX.h" - -using namespace lldb; -using namespace lldb_private; - -MachThreadContext_i386::MachThreadContext_i386 (ThreadMacOSX &thread) : - MachThreadContext (thread), - m_flags_reg(LLDB_INVALID_REGNUM) -{ -} - -MachThreadContext_i386::~MachThreadContext_i386() -{ -} - - -MachThreadContext* -MachThreadContext_i386::Create (const ArchSpec &arch_spec, ThreadMacOSX &thread) -{ - return new MachThreadContext_i386(thread); -} - -// Class init function -void -MachThreadContext_i386::Initialize() -{ - llvm::Triple triple; - triple.setArch (llvm::Triple::x86); - triple.setVendor (llvm::Triple::Apple); - triple.setOS (llvm::Triple::Darwin); - ArchSpec arch_spec (triple); - ProcessMacOSX::AddArchCreateCallback(arch_spec, MachThreadContext_i386::Create); -} - -// Instance init function -void -MachThreadContext_i386::InitializeInstance() -{ - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx != NULL); - m_flags_reg = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); -} - -void -MachThreadContext_i386::ThreadWillResume() -{ - m_thread.GetRegisterContext()->HardwareSingleStep (m_thread.GetState() == eStateStepping); -} - -bool -MachThreadContext_i386::ShouldStop() -{ - return true; -} - -void -MachThreadContext_i386::RefreshStateAfterStop() -{ - m_thread.GetRegisterContext()->HardwareSingleStep (false); -} - -bool -MachThreadContext_i386::NotifyException (MachException::Data& exc) -{ - switch (exc.exc_type) - { - case EXC_BAD_ACCESS: - break; - case EXC_BAD_INSTRUCTION: - break; - case EXC_ARITHMETIC: - break; - case EXC_EMULATION: - break; - case EXC_SOFTWARE: - break; - case EXC_BREAKPOINT: - if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 2) - { - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx); - lldb::addr_t pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS); - if (pc != LLDB_INVALID_ADDRESS && pc > 0) - { - pc -= 1; - reg_ctx->SetPC(pc); - } - return true; - } - break; - case EXC_SYSCALL: - break; - case EXC_MACH_SYSCALL: - break; - case EXC_RPC_ALERT: - break; - } - return false; -} - - -// Set the single step bit in the processor status register. -//kern_return_t -//MachThreadContext_i386::EnableHardwareSingleStep (bool enable) -//{ -// RegisterContext *reg_ctx = m_thread.GetRegisterContext(); -// assert (reg_ctx); -// Scalar rflags_scalar; -// -// if (reg_ctx->ReadRegisterValue (m_flags_reg, rflags_scalar)) -// { -// Flags rflags(rflags_scalar.UInt()); -// const uint32_t trace_bit = 0x100u; -// if (enable) -// { -// // If the trace bit is already cleared, there is nothing to do -// if (rflags.IsSet (trace_bit)) -// return KERN_SUCCESS; -// else -// rflags.Set (trace_bit); -// } -// else -// { -// // If the trace bit is already cleared, there is nothing to do -// if (rflags.IsClear (trace_bit)) -// return KERN_SUCCESS; -// else -// rflags.Clear(trace_bit); -// } -// -// rflags_scalar = rflags.Get(); -// // If the code makes it here we have changes to the GPRs which -// // we need to write back out, so lets do that. -// if (reg_ctx->WriteRegisterValue(m_flags_reg, rflags_scalar)) -// return KERN_SUCCESS; -// } -// // Return the error code for reading the GPR registers back -// return KERN_INVALID_ARGUMENT; -//} - -RegisterContextSP -MachThreadContext_i386::CreateRegisterContext (StackFrame *frame) const -{ - lldb::RegisterContextSP reg_ctx_sp (new RegisterContextMach_i386(m_thread, frame->GetConcreteFrameIndex())); - return reg_ctx_sp; -} - - -size_t -MachThreadContext_i386::GetStackFrameData(StackFrame *first_frame, std::vector<std::pair<lldb::addr_t, lldb::addr_t> >& fp_pc_pairs) -{ - fp_pc_pairs.clear(); - - std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair; - - struct Frame_i386 - { - uint32_t fp; - uint32_t pc; - }; - - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx); - - Frame_i386 frame = { reg_ctx->GetFP(0), reg_ctx->GetPC(LLDB_INVALID_ADDRESS) }; - - fp_pc_pairs.push_back(std::make_pair(frame.fp, frame.pc)); - - const size_t k_frame_size = sizeof(frame); - Error error; - - while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) - { - // Read both the FP and PC (8 bytes) - if (m_thread.GetProcess().ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size) - break; - - if (frame.pc != 0) - fp_pc_pairs.push_back(std::make_pair(frame.fp, frame.pc)); - } - if (!fp_pc_pairs.empty()) - { - lldb::addr_t first_frame_pc = fp_pc_pairs.front().second; - if (first_frame_pc != LLDB_INVALID_ADDRESS) - { - const uint32_t resolve_scope = eSymbolContextModule | - eSymbolContextCompUnit | - eSymbolContextFunction | - eSymbolContextSymbol; - - SymbolContext first_frame_sc(first_frame->GetSymbolContext(resolve_scope)); - const AddressRange *addr_range_ptr = NULL; - if (first_frame_sc.function) - addr_range_ptr = &first_frame_sc.function->GetAddressRange(); - else if (first_frame_sc.symbol) - addr_range_ptr = first_frame_sc.symbol->GetAddressRangePtr(); - - if (addr_range_ptr) - { - if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) - { - // We are at the first instruction, so we can recover the - // previous PC by dereferencing the SP - lldb::addr_t first_frame_sp = reg_ctx->GetSP(0); - // Read the real second frame return address into frame.pc - if (m_thread.GetProcess().ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc)) - { - // Construct a correct second frame (we already read the pc for it above - frame.fp = fp_pc_pairs.front().first; - - // Insert the frame - fp_pc_pairs.insert(fp_pc_pairs.begin()+1, std::make_pair(frame.fp, frame.pc)); - - // Correct the fp in the first frame to use the SP - fp_pc_pairs.front().first = first_frame_sp; - } - } - } - } - } - return fp_pc_pairs.size(); -} - - -#endif // #if defined (__i386__) diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.h b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.h deleted file mode 100644 index 6326a8bdcce..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.h +++ /dev/null @@ -1,56 +0,0 @@ -//===-- MachThreadContext_i386.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_MachThreadContext_i386_h_ -#define liblldb_MachThreadContext_i386_h_ - -#if defined (__i386__) || defined (__x86_64__) - -#include "MachThreadContext.h" -#include "RegisterContextMach_i386.h" - -class ThreadMacOSX; - -class MachThreadContext_i386 : public MachThreadContext -{ -public: - static MachThreadContext* Create(const lldb_private::ArchSpec &arch_spec, ThreadMacOSX &thread); - - // Class init function - static void Initialize(); - - MachThreadContext_i386(ThreadMacOSX &thread); - - virtual - ~MachThreadContext_i386(); - - virtual lldb::RegisterContextSP - CreateRegisterContext (lldb_private::StackFrame *frame) const; - - virtual void InitializeInstance(); - virtual void ThreadWillResume(); - virtual bool ShouldStop (); - virtual void RefreshStateAfterStop(); - - virtual bool NotifyException(MachException::Data& exc); - virtual size_t GetStackFrameData(lldb_private::StackFrame *first_frame, std::vector<std::pair<lldb::addr_t, lldb::addr_t> >& fp_pc_pairs); - -protected: -// kern_return_t EnableHardwareSingleStep (bool enable); - uint32_t m_flags_reg; -private: - DISALLOW_COPY_AND_ASSIGN (MachThreadContext_i386); -}; - -//#if defined (__i386__) -//typedef MachThreadContext_i386 DNBArch; -//#endif - -#endif // defined (__i386__) || defined (__x86_64__) -#endif // #ifndef liblldb_MachThreadContext_i386_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.cpp deleted file mode 100644 index a31713edd85..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.cpp +++ /dev/null @@ -1,256 +0,0 @@ -//===-- MachThreadContext_x86_64.cpp ----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#if defined (__i386__) || defined (__x86_64__) - -#include <sys/cdefs.h> - -#include "llvm/ADT/Triple.h" - -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/Symbol.h" - -#include "MachThreadContext_x86_64.h" -#include "ProcessMacOSX.h" -#include "ThreadMacOSX.h" - -using namespace lldb; -using namespace lldb_private; - -MachThreadContext_x86_64::MachThreadContext_x86_64(ThreadMacOSX &thread) : - MachThreadContext (thread), - m_flags_reg(LLDB_INVALID_REGNUM) -{ -} - -MachThreadContext_x86_64::~MachThreadContext_x86_64() -{ -} - -MachThreadContext* -MachThreadContext_x86_64::Create(const ArchSpec &arch_spec, ThreadMacOSX &thread) -{ - return new MachThreadContext_x86_64(thread); -} - -// Class init function -void -MachThreadContext_x86_64::Initialize() -{ - llvm::Triple triple; - triple.setArch (llvm::Triple::x86_64); - triple.setVendor (llvm::Triple::Apple); - triple.setOS (llvm::Triple::Darwin); - ArchSpec arch_spec (triple); - ProcessMacOSX::AddArchCreateCallback(arch_spec, MachThreadContext_x86_64::Create); -} - -// Instance init function -void -MachThreadContext_x86_64::InitializeInstance() -{ - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx != NULL); - m_flags_reg = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); -} - -void -MachThreadContext_x86_64::ThreadWillResume() -{ - m_thread.GetRegisterContext()->HardwareSingleStep (m_thread.GetState() == eStateStepping); -} - -bool -MachThreadContext_x86_64::ShouldStop() -{ - return true; -} - -void -MachThreadContext_x86_64::RefreshStateAfterStop() -{ - m_thread.GetRegisterContext()->HardwareSingleStep (false); -} - -bool -MachThreadContext_x86_64::NotifyException(MachException::Data& exc) -{ - switch (exc.exc_type) - { - case EXC_BAD_ACCESS: - break; - case EXC_BAD_INSTRUCTION: - break; - case EXC_ARITHMETIC: - break; - case EXC_EMULATION: - break; - case EXC_SOFTWARE: - break; - case EXC_BREAKPOINT: - if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 2) - { - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx); - lldb::addr_t pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS); - if (pc != LLDB_INVALID_ADDRESS && pc > 0) - { - pc -= 1; - reg_ctx->SetPC(pc); - } - return true; - } - break; - case EXC_SYSCALL: - break; - case EXC_MACH_SYSCALL: - break; - case EXC_RPC_ALERT: - break; - } - return false; -} - - -// Set the single step bit in the processor status register. -//kern_return_t -//MachThreadContext_x86_64::EnableHardwareSingleStep (bool enable) -//{ -// RegisterContext *reg_ctx = m_thread.GetRegisterContext(); -// assert (reg_ctx); -// Scalar rflags_scalar; -// -// if (reg_ctx->ReadRegisterValue (m_flags_reg, rflags_scalar)) -// { -// Flags rflags(rflags_scalar.UInt()); -// const uint32_t trace_bit = 0x100u; -// if (enable) -// { -// // If the trace bit is already set, there is nothing to do -// if (rflags.IsSet (trace_bit)) -// return KERN_SUCCESS; -// else -// rflags.Set (trace_bit); -// } -// else -// { -// // If the trace bit is already cleared, there is nothing to do -// if (rflags.IsClear (trace_bit)) -// return KERN_SUCCESS; -// else -// rflags.Clear(trace_bit); -// } -// -// rflags_scalar = rflags.Get(); -// // If the code makes it here we have changes to the GPRs which -// // we need to write back out, so lets do that. -// if (reg_ctx->WriteRegisterValue(m_flags_reg, rflags_scalar)) -// return KERN_SUCCESS; -// } -// // Return the error code for reading the GPR registers back -// return KERN_INVALID_ARGUMENT; -//} -// - -//---------------------------------------------------------------------- -// Register information defintions for 32 bit PowerPC. -//---------------------------------------------------------------------- - - - -RegisterContextSP -MachThreadContext_x86_64::CreateRegisterContext (StackFrame *frame) const -{ - lldb::RegisterContextSP reg_ctx_sp (new RegisterContextMach_x86_64(m_thread, frame->GetConcreteFrameIndex())); - return reg_ctx_sp; -} - - -//bool -//MachThreadContext_x86_64::RegisterSetStateIsValid (uint32_t set) const -//{ -// return m_state.RegisterSetIsCached(set); -//} - - -size_t -MachThreadContext_x86_64::GetStackFrameData(StackFrame *first_frame, std::vector<std::pair<lldb::addr_t, lldb::addr_t> >& fp_pc_pairs) -{ - fp_pc_pairs.clear(); - - std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair; - - struct Frame_x86_64 - { - uint64_t fp; - uint64_t pc; - }; - - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx); - - Frame_x86_64 frame = { reg_ctx->GetFP(0), reg_ctx->GetPC(LLDB_INVALID_ADDRESS) }; - - fp_pc_pairs.push_back(std::make_pair(frame.fp, frame.pc)); - Error error; - const size_t k_frame_size = sizeof(frame); - while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) - { - // Read both the FP and PC (16 bytes) - if (m_thread.GetProcess().ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size) - break; - - if (frame.pc >= 0x1000) - fp_pc_pairs.push_back(std::make_pair(frame.fp, frame.pc)); - } - if (!fp_pc_pairs.empty()) - { - lldb::addr_t first_frame_pc = fp_pc_pairs.front().second; - if (first_frame_pc != LLDB_INVALID_ADDRESS) - { - const uint32_t resolve_scope = eSymbolContextModule | - eSymbolContextCompUnit | - eSymbolContextFunction | - eSymbolContextSymbol; - - SymbolContext first_frame_sc(first_frame->GetSymbolContext(resolve_scope)); - const AddressRange *addr_range_ptr = NULL; - if (first_frame_sc.function) - addr_range_ptr = &first_frame_sc.function->GetAddressRange(); - else if (first_frame_sc.symbol) - addr_range_ptr = first_frame_sc.symbol->GetAddressRangePtr(); - - if (addr_range_ptr) - { - if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) - { - // We are at the first instruction, so we can recover the - // previous PC by dereferencing the SP - lldb::addr_t first_frame_sp = reg_ctx->GetSP(0); - // Read the real second frame return address into frame.pc - if (m_thread.GetProcess().ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc)) - { - // Construct a correct second frame (we already read the pc for it above - frame.fp = fp_pc_pairs.front().first; - - // Insert the frame - fp_pc_pairs.insert(fp_pc_pairs.begin()+1, std::make_pair(frame.fp, frame.pc)); - - // Correct the fp in the first frame to use the SP - fp_pc_pairs.front().first = first_frame_sp; - } - } - } - } - } - return fp_pc_pairs.size(); -} - - -#endif // #if defined (__i386__) || defined (__x86_64__) diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.h b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.h deleted file mode 100644 index 61e60c17fae..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.h +++ /dev/null @@ -1,69 +0,0 @@ -//===-- MachThreadContext_x86_64.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_MachThreadContext_x86_64_h_ -#define liblldb_MachThreadContext_x86_64_h_ - -#if defined (__i386__) || defined (__x86_64__) - -#include "MachThreadContext.h" -#include "RegisterContextMach_x86_64.h" - -class ThreadMacOSX; - -class MachThreadContext_x86_64 : public MachThreadContext -{ -public: - static MachThreadContext* - Create(const lldb_private::ArchSpec &arch_spec, ThreadMacOSX &thread); - - // Class init function - static void - Initialize(); - - // Instance init function - void - InitializeInstance(); - - MachThreadContext_x86_64 (ThreadMacOSX &thread); - - virtual - ~MachThreadContext_x86_64(); - - virtual lldb::RegisterContextSP - CreateRegisterContext (lldb_private::StackFrame *frame) const; - - virtual void - ThreadWillResume (); - - virtual bool - ShouldStop (); - - virtual void - RefreshStateAfterStop (); - - virtual bool - NotifyException (MachException::Data& exc); - - virtual size_t - GetStackFrameData (lldb_private::StackFrame *first_frame, std::vector<std::pair<lldb::addr_t, lldb::addr_t> >& fp_pc_pairs); - -protected: -// kern_return_t EnableHardwareSingleStep (bool enable); - uint32_t m_flags_reg; -private: - DISALLOW_COPY_AND_ASSIGN (MachThreadContext_x86_64); -}; - -//#if defined (__x86_64__) -//typedef MachThreadContext_x86_64 DNBArch; -//#endif - -#endif // defined (__i386__) || defined (__x86_64__) -#endif // #ifndef liblldb_MachThreadContext_x86_64_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMMemory.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMMemory.cpp deleted file mode 100644 index 59ff66dadc2..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMMemory.cpp +++ /dev/null @@ -1,196 +0,0 @@ -//===-- MachVMMemory.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "MachVMMemory.h" - -#include <mach/mach_vm.h> - -#include "MachVMRegion.h" -#include "ProcessMacOSXLog.h" - -using namespace lldb; -using namespace lldb_private; - -MachVMMemory::MachVMMemory() : - m_page_size (kInvalidPageSize) -{ -} - -MachVMMemory::~MachVMMemory() -{ -} - -size_t -MachVMMemory::PageSize(lldb_private::Error &error) -{ - if (m_page_size == kInvalidPageSize) - { - error = ::host_page_size( ::mach_host_self(), &m_page_size); - if (error.Fail()) - m_page_size = 0; - } - - if (m_page_size != 0 && m_page_size != kInvalidPageSize) - { - if (error.Success()) - error.SetErrorString ("unable to determine page size"); - } - return m_page_size; -} - -size_t -MachVMMemory::MaxBytesLeftInPage (lldb::addr_t addr, size_t count) -{ - Error error; - const size_t page_size = PageSize(error); - if (page_size > 0) - { - size_t page_offset = (addr % page_size); - size_t bytes_left_in_page = page_size - page_offset; - if (count > bytes_left_in_page) - count = bytes_left_in_page; - } - return count; -} - -size_t -MachVMMemory::Read(task_t task, lldb::addr_t address, void *data, size_t data_count, Error &error) -{ - if (data == NULL || data_count == 0) - return 0; - - size_t total_bytes_read = 0; - lldb::addr_t curr_addr = address; - uint8_t *curr_data = (uint8_t*)data; - while (total_bytes_read < data_count) - { - mach_vm_size_t curr_size = MaxBytesLeftInPage(curr_addr, data_count - total_bytes_read); - mach_msg_type_number_t curr_bytes_read = 0; - vm_offset_t vm_memory = NULL; - error = ::mach_vm_read (task, curr_addr, curr_size, &vm_memory, &curr_bytes_read); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_MEMORY|PD_LOG_VERBOSE)); - - if (log || error.Fail()) - error.PutToLog (log.get(), "::mach_vm_read (task = 0x%4.4x, addr = 0x%8.8llx, size = %llu, data => %8.8p, dataCnt => %i)", task, (uint64_t)curr_addr, (uint64_t)curr_size, vm_memory, curr_bytes_read); - - if (error.Success()) - { - if (curr_bytes_read != curr_size) - { - if (log) - error.PutToLog (log.get(), "::mach_vm_read (task = 0x%4.4x, addr = 0x%8.8llx, size = %llu, data => %8.8p, dataCnt=>%i) only read %u of %llu bytes", task, (uint64_t)curr_addr, (uint64_t)curr_size, vm_memory, curr_bytes_read, curr_bytes_read, (uint64_t)curr_size); - } - ::memcpy (curr_data, (void *)vm_memory, curr_bytes_read); - ::vm_deallocate (mach_task_self (), vm_memory, curr_bytes_read); - total_bytes_read += curr_bytes_read; - curr_addr += curr_bytes_read; - curr_data += curr_bytes_read; - } - else - { - break; - } - } - return total_bytes_read; -} - - -size_t -MachVMMemory::Write(task_t task, lldb::addr_t address, const void *data, size_t data_count, Error &error) -{ - MachVMRegion vmRegion(task); - - size_t total_bytes_written = 0; - lldb::addr_t curr_addr = address; - const uint8_t *curr_data = (const uint8_t*)data; - - - while (total_bytes_written < data_count) - { - if (vmRegion.GetRegionForAddress(curr_addr)) - { - mach_vm_size_t curr_data_count = data_count - total_bytes_written; - mach_vm_size_t region_bytes_left = vmRegion.BytesRemaining(curr_addr); - if (region_bytes_left == 0) - { - break; - } - if (curr_data_count > region_bytes_left) - curr_data_count = region_bytes_left; - - if (vmRegion.SetProtections(curr_addr, curr_data_count, VM_PROT_READ | VM_PROT_WRITE)) - { - size_t bytes_written = WriteRegion(task, curr_addr, curr_data, curr_data_count, error); - if (bytes_written <= 0) - { - // Error should have already be posted by WriteRegion... - break; - } - else - { - total_bytes_written += bytes_written; - curr_addr += bytes_written; - curr_data += bytes_written; - } - } - else - { - ProcessMacOSXLog::LogIf (PD_LOG_MEMORY_PROTECTIONS, "Failed to set read/write protections on region for address: [0x%8.8llx-0x%8.8llx)", (uint64_t)curr_addr, (uint64_t)(curr_addr + curr_data_count)); - break; - } - } - else - { - ProcessMacOSXLog::LogIf (PD_LOG_MEMORY_PROTECTIONS, "Failed to get region for address: 0x%8.8llx", (uint64_t)address); - break; - } - } - - return total_bytes_written; -} - - -size_t -MachVMMemory::WriteRegion(task_t task, const lldb::addr_t address, const void *data, const size_t data_count, Error &error) -{ - if (data == NULL || data_count == 0) - return 0; - - size_t total_bytes_written = 0; - lldb::addr_t curr_addr = address; - const uint8_t *curr_data = (const uint8_t*)data; - while (total_bytes_written < data_count) - { - mach_msg_type_number_t curr_data_count = MaxBytesLeftInPage(curr_addr, data_count - total_bytes_written); - error = ::mach_vm_write (task, curr_addr, (pointer_t) curr_data, curr_data_count); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_MEMORY)); - if (log || error.Fail()) - error.PutToLog (log.get(), "::mach_vm_write ( task = 0x%4.4x, addr = 0x%8.8llx, data = %8.8p, dataCnt = %u )", task, (uint64_t)curr_addr, curr_data, curr_data_count); - -#if defined (__powerpc__) || defined (__ppc__) - vm_machine_attribute_val_t mattr_value = MATTR_VAL_CACHE_FLUSH; - - error = ::vm_machine_attribute (task, curr_addr, curr_data_count, MATTR_CACHE, &mattr_value); - if (log || error.Fail()) - error.Log(log.get(), "::vm_machine_attribute ( task = 0x%4.4x, addr = 0x%8.8llx, size = %u, attr = MATTR_CACHE, mattr_value => MATTR_VAL_CACHE_FLUSH )", task, (uint64_t)curr_addr, curr_data_count); -#endif - - if (error.Success()) - { - total_bytes_written += curr_data_count; - curr_addr += curr_data_count; - curr_data += curr_data_count; - } - else - { - break; - } - } - return total_bytes_written; -} diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMMemory.h b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMMemory.h deleted file mode 100644 index 866fa369706..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMMemory.h +++ /dev/null @@ -1,36 +0,0 @@ -//===-- MachVMMemory.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_MachVMMemory_h_ -#define liblldb_MachVMMemory_h_ - -#include <mach/mach.h> - -#include "lldb/lldb-private.h" -#include "lldb/Core/Error.h" - -class MachVMMemory -{ -public: - enum { kInvalidPageSize = ~0 }; - MachVMMemory(); - ~MachVMMemory(); - size_t Read(task_t task, lldb::addr_t address, void *data, size_t data_count, lldb_private::Error &error); - size_t Write(task_t task, lldb::addr_t address, const void *data, size_t data_count, lldb_private::Error &error); - size_t PageSize(lldb_private::Error &error); - -protected: - size_t MaxBytesLeftInPage(lldb::addr_t addr, size_t count); - - size_t WriteRegion(task_t task, const lldb::addr_t address, const void *data, const size_t data_count, lldb_private::Error &error); - vm_size_t m_page_size; -}; - - -#endif // #ifndef liblldb_MachVMMemory_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMRegion.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMRegion.cpp deleted file mode 100644 index 00a58941a15..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMRegion.cpp +++ /dev/null @@ -1,184 +0,0 @@ -//===-- MachVMRegion.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include <assert.h> -#include <mach/mach_vm.h> -#include "MachVMRegion.h" -#include "ProcessMacOSXLog.h" - -using namespace lldb; -using namespace lldb_private; - -MachVMRegion::MachVMRegion(task_t task) : - m_task(task), - m_addr(LLDB_INVALID_ADDRESS), - m_err(), - m_start(LLDB_INVALID_ADDRESS), - m_size(0), - m_depth(-1), - m_data(), - m_curr_protection(0), - m_protection_addr(LLDB_INVALID_ADDRESS), - m_protection_size(0) -{ - memset(&m_data, 0, sizeof(m_data)); -} - -MachVMRegion::~MachVMRegion() -{ - // Restore any original protections and clear our vars - Clear(); -} - -void -MachVMRegion::Clear() -{ - RestoreProtections(); - m_addr = LLDB_INVALID_ADDRESS; - m_err.Clear(); - m_start = LLDB_INVALID_ADDRESS; - m_size = 0; - m_depth = -1; - memset(&m_data, 0, sizeof(m_data)); - m_curr_protection = 0; - m_protection_addr = LLDB_INVALID_ADDRESS; - m_protection_size = 0; -} - -bool -MachVMRegion::SetProtections(mach_vm_address_t addr, mach_vm_size_t size, vm_prot_t prot) -{ - if (ContainsAddress(addr)) - { - mach_vm_size_t prot_size = size; - mach_vm_address_t end_addr = EndAddress(); - if (prot_size > (end_addr - addr)) - prot_size = end_addr - addr; - - - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_MEMORY_PROTECTIONS)); - if (prot_size > 0) - { - if (prot == (m_curr_protection & VM_PROT_ALL)) - { - if (log) - log->Printf ("MachVMRegion::%s: protections (%u) already sufficient for task 0x%4.4x at address 0x%8.8llx) ", __FUNCTION__, prot, m_task, (uint64_t)addr); - // Protections are already set as requested... - return true; - } - else - { - m_err = ::mach_vm_protect (m_task, addr, prot_size, 0, prot); - if (log || m_err.Fail()) - m_err.PutToLog(log.get(), "::mach_vm_protect ( task = 0x%4.4x, addr = 0x%8.8llx, size = %llu, set_max = %i, prot = %u )", m_task, (uint64_t)addr, (uint64_t)prot_size, 0, prot); - if (m_err.Fail()) - { - // Try again with the ability to create a copy on write region - m_err = ::mach_vm_protect (m_task, addr, prot_size, 0, prot | VM_PROT_COPY); - if (log || m_err.Fail()) - m_err.PutToLog(log.get(), "::mach_vm_protect ( task = 0x%4.4x, addr = 0x%8.8llx, size = %llu, set_max = %i, prot = %u )", m_task, (uint64_t)addr, (uint64_t)prot_size, 0, prot | VM_PROT_COPY); - } - if (m_err.Success()) - { - m_curr_protection = prot; - m_protection_addr = addr; - m_protection_size = prot_size; - return true; - } - } - } - else - { - log->Printf("MachVMRegion::%s: Zero size for task 0x%4.4x at address 0x%8.8llx) ", __FUNCTION__, m_task, (uint64_t)addr); - } - } - return false; -} - -bool -MachVMRegion::RestoreProtections() -{ - if (m_curr_protection != m_data.protection && m_protection_size > 0) - { - m_err = ::mach_vm_protect (m_task, m_protection_addr, m_protection_size, 0, m_data.protection); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_MEMORY_PROTECTIONS)); - if (log || m_err.Fail()) - m_err.PutToLog(log.get(), "::mach_vm_protect ( task = 0x%4.4x, addr = 0x%8.8llx, size = %llu, set_max = %i, prot = %u )", m_task, (uint64_t)m_protection_addr, (uint64_t)m_protection_size, 0, m_data.protection); - if (m_err.Success()) - { - m_protection_size = 0; - m_protection_addr = LLDB_INVALID_ADDRESS; - m_curr_protection = m_data.protection; - return true; - } - } - else - { - m_err.Clear(); - return true; - } - - return false; -} - -bool -MachVMRegion::GetRegionForAddress(lldb::addr_t addr) -{ - // Restore any original protections and clear our vars - Clear(); - m_addr = addr; - m_start = addr; - m_depth = 1024; - mach_msg_type_number_t info_size = kRegionInfoSize; - assert(sizeof(info_size) == 4); - m_err = ::mach_vm_region_recurse (m_task, &m_start, &m_size, &m_depth, (vm_region_recurse_info_t)&m_data, &info_size); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_MEMORY_PROTECTIONS)); - if (log || m_err.Fail()) - m_err.PutToLog(log.get(), "::mach_vm_region_recurse ( task = 0x%4.4x, address => 0x%8.8llx, size => %llu, nesting_depth => %d, info => %p, infoCnt => %d) addr = 0x%8.8llx ", m_task, (uint64_t)m_start, (uint64_t)m_size, m_depth, &m_data, info_size, (uint64_t)addr); - if (m_err.Fail()) - { - return false; - } - else - { - if (log && log->GetMask().Test(PD_LOG_VERBOSE)) - { - log->Printf("info = { prot = %u, " - "max_prot = %u, " - "inheritance = 0x%8.8x, " - "offset = 0x%8.8llx, " - "user_tag = 0x%8.8x, " - "ref_count = %u, " - "shadow_depth = %u, " - "ext_pager = %u, " - "share_mode = %u, " - "is_submap = %d, " - "behavior = %d, " - "object_id = 0x%8.8x, " - "user_wired_count = 0x%4.4x }", - m_data.protection, - m_data.max_protection, - m_data.inheritance, - (uint64_t)m_data.offset, - m_data.user_tag, - m_data.ref_count, - m_data.shadow_depth, - m_data.external_pager, - m_data.share_mode, - m_data.is_submap, - m_data.behavior, - m_data.object_id, - m_data.user_wired_count); - } - } - - m_curr_protection = m_data.protection; - - return true; -} diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMRegion.h b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMRegion.h deleted file mode 100644 index b12353df823..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/MachVMRegion.h +++ /dev/null @@ -1,63 +0,0 @@ -//===-- MachVMRegion.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_MachVMRegion_h_ -#define liblldb_MachVMRegion_h_ - -#include <mach/mach.h> -#include "lldb/lldb-private.h" -#include "lldb/Core/Error.h" - -class MachVMRegion -{ -public: - MachVMRegion(task_t task); - ~MachVMRegion(); - - void Clear(); - mach_vm_address_t StartAddress() const { return m_start; } - mach_vm_address_t EndAddress() const { return m_start + m_size; } - mach_vm_address_t BytesRemaining(mach_vm_address_t addr) const - { - if (ContainsAddress(addr)) - return m_size - (addr - m_start); - else - return 0; - } - bool ContainsAddress(mach_vm_address_t addr) const - { - return addr >= StartAddress() && addr < EndAddress(); - } - - bool SetProtections(mach_vm_address_t addr, mach_vm_size_t size, vm_prot_t prot); - bool RestoreProtections(); - bool GetRegionForAddress(lldb::addr_t addr); -protected: -#if defined (VM_REGION_SUBMAP_SHORT_INFO_COUNT_64) - typedef vm_region_submap_short_info_data_64_t RegionInfo; - enum { kRegionInfoSize = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64 }; -#else - typedef vm_region_submap_info_data_64_t RegionInfo; - enum { kRegionInfoSize = VM_REGION_SUBMAP_INFO_COUNT_64 }; -#endif - - task_t m_task; - mach_vm_address_t m_addr; - lldb_private::Error m_err; - mach_vm_address_t m_start; - mach_vm_size_t m_size; - natural_t m_depth; - RegionInfo m_data; - vm_prot_t m_curr_protection; // The current, possibly modified protections. Original value is saved in m_data.protections. - mach_vm_address_t m_protection_addr; // The start address at which protections were changed - mach_vm_size_t m_protection_size; // The size of memory that had its protections changed - -}; - -#endif // #ifndef liblldb_MachVMRegion_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/ProcessControl-mig.defs b/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/ProcessControl-mig.defs deleted file mode 100644 index 7f16fe13356..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/MacOSX/ProcessControl-mig.defs +++ /dev/null @@ -1,16 +0,0 @@ -/* - * nub.defs - */ - -/* - * DNBConfig.h is autogenerated by a perl script that is run as a build - * script in XCode. XCode is responsible for calling the script and setting - * the include paths correctly to locate it. The file will exist in the - * derived sources directory in the build folder. - * - */ - -#include "DNBConfig.h" - - -#include <mach/mach_exc.defs> diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp deleted file mode 100644 index c55143266ef..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp +++ /dev/null @@ -1,2107 +0,0 @@ -//===-- ProcessMacOSX.cpp ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> -#include <mach/mach.h> -#include <mach/mach_vm.h> -#include <spawn.h> -#include <sys/fcntl.h> -#include <sys/types.h> -#include <sys/ptrace.h> -#include <sys/stat.h> -#include <sys/sysctl.h> -#include <unistd.h> - -// C++ Includes -#include <algorithm> -#include <map> - -// Other libraries and framework includes - -#include "lldb/Breakpoint/WatchpointLocation.h" -#include "lldb/Core/ArchSpec.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Core/Timer.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/TimeValue.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Target/DynamicLoader.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/TargetList.h" -#include "lldb/Utility/PseudoTerminal.h" - -#if defined (__arm__) - -#include <CoreFoundation/CoreFoundation.h> -#include <SpringBoardServices/SpringBoardServer.h> -#include <SpringBoardServices/SBSWatchdogAssertion.h> - -#endif // #if defined (__arm__) - -// Project includes -#include "ProcessMacOSX.h" -#include "ProcessMacOSXLog.h" -#include "ThreadMacOSX.h" - - -#if 0 -#define DEBUG_LOG(fmt, ...) printf(fmt, ## __VA_ARGS__) -#else -#define DEBUG_LOG(fmt, ...) -#endif - -#ifndef MACH_PROCESS_USE_POSIX_SPAWN -#define MACH_PROCESS_USE_POSIX_SPAWN 1 -#endif - -#ifndef _POSIX_SPAWN_DISABLE_ASLR -#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 -#endif - -#if defined (__arm__) - -static bool -IsSBProcess (lldb::pid_t pid) -{ - bool opt_runningApps = true; - bool opt_debuggable = false; - - CFReleaser<CFArrayRef> sbsAppIDs (::SBSCopyApplicationDisplayIdentifiers (opt_runningApps, opt_debuggable)); - if (sbsAppIDs.get() != NULL) - { - CFIndex count = ::CFArrayGetCount (sbsAppIDs.get()); - CFIndex i = 0; - for (i = 0; i < count; i++) - { - CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i); - - // Get the process id for the app (if there is one) - lldb::pid_t sbs_pid = LLDB_INVALID_PROCESS_ID; - if (::SBSProcessIDForDisplayIdentifier ((CFStringRef)displayIdentifier, &sbs_pid) == TRUE) - { - if (sbs_pid == pid) - return true; - } - } - } - return false; -} - - -#endif // #if defined (__arm__) - -using namespace lldb; -using namespace lldb_private; -// -//void * -//ProcessMacOSX::WaitForChildProcessToExit (void *pid_ptr) -//{ -// const lldb::pid_t pid = *((lldb::user_id_t *)pid_ptr); -// -// LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_THREAD)); -// -// if (log) -// log->Printf ("ProcessMacOSX::%s (arg = %p) thread starting...", __FUNCTION__, pid_ptr); -// -// int status = -1; -// -// while (1) -// { -// if (log) -// log->Printf("::waitpid (pid = %i, stat_loc = %p, options = 0)...", pid, &status); -// -// lldb::pid_t return_pid = ::waitpid (pid, &status, 0); -// -// if (return_pid < 0) -// { -// if (log) -// log->Printf("%s ::waitpid (pid = %i, stat_loc = %p, options = 0) => errno = %i, status = 0x%8.8x", pid, &status, errno, status); -// break; -// } -// -// bool set_exit_status = false; -// if (WIFSTOPPED(status)) -// { -// if (log) -// log->Printf("::waitpid (pid = %i, stat_loc = %p, options = 0) => return_pid = %i, status = 0x%8.8x (STOPPED)", pid, &status, return_pid, status); -// } -// else if (WIFEXITED(status)) -// { -// set_exit_status = true; -// if (log) -// log->Printf("::waitpid (pid = %i, stat_loc = %p, options = 0) => return_pid = %i, status = 0x%8.8x (EXITED)", pid, &status, return_pid, status); -// } -// else if (WIFSIGNALED(status)) -// { -// set_exit_status = true; -// if (log) -// log->Printf("::waitpid (pid = %i, stat_loc = %p, options = 0) => return_pid = %i, status = 0x%8.8x (SIGNALED)", pid, &status, return_pid, status); -// } -// else -// { -// if (log) -// log->Printf("::waitpid (pid = %i, stat_loc = %p, options = 0) => return_pid = %i, status = 0x%8.8x", pid, &status, return_pid, status); -// } -// -// if (set_exit_status) -// { -// // Try and deliver the news to the process if it is still around -// TargetSP target_sp(TargetList::SharedList().FindTargetWithProcessID (return_pid)); -// if (target_sp.get()) -// { -// ProcessMacOSX *process = dynamic_cast<ProcessMacOSX*>(target_sp->GetProcess().get()); -// if (process) -// { -// process->SetExitStatus (status); -// if (log) -// log->Printf("Setting exit status of %i to 0x%8.8x", pid, status); -// process->Task().ShutDownExceptionThread(); -// } -// } -// // Break out of the loop and return. -// break; -// } -// } -// -// if (log) -// log->Printf ("ProcessMacOSX::%s (arg = %p) thread exiting...", __FUNCTION__, pid_ptr); -// -// return NULL; -//} -// - -const char * -ProcessMacOSX::GetPluginNameStatic() -{ - return "macosx-user"; -} - -const char * -ProcessMacOSX::GetPluginDescriptionStatic() -{ - return "Native MacOSX user process debugging plug-in."; -} - -void -ProcessMacOSX::Terminate() -{ - PluginManager::UnregisterPlugin (ProcessMacOSX::CreateInstance); -} - - -Process* -ProcessMacOSX::CreateInstance (Target &target, Listener &listener) -{ - ProcessMacOSX::Initialize(); - - return new ProcessMacOSX (target, listener); -} - -bool -ProcessMacOSX::CanDebug(Target &target, bool plugin_specified_by_name) -{ - // For now we are just making sure the file exists for a given module - ModuleSP exe_module_sp(target.GetExecutableModule()); - if (exe_module_sp.get()) - return exe_module_sp->GetFileSpec().Exists(); - return false; -} - -//---------------------------------------------------------------------- -// ProcessMacOSX constructor -//---------------------------------------------------------------------- -ProcessMacOSX::ProcessMacOSX(Target& target, Listener &listener) : - Process (target, listener), - m_stdio_ours (false), - m_child_stdin (-1), - m_child_stdout (-1), - m_child_stderr (-1), - m_task (this), - m_flags (eFlagsNone), - m_stdio_thread (LLDB_INVALID_HOST_THREAD), - m_monitor_thread (LLDB_INVALID_HOST_THREAD), - m_stdio_mutex (Mutex::eMutexTypeRecursive), - m_stdout_data (), - m_exception_messages (), - m_exception_messages_mutex (Mutex::eMutexTypeRecursive), - m_arch_spec () -{ -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -ProcessMacOSX::~ProcessMacOSX() -{ -// m_mach_process.UnregisterNotificationCallbacks (this); - Clear(); - -} - -//---------------------------------------------------------------------- -// PluginInterface -//---------------------------------------------------------------------- -const char * -ProcessMacOSX::GetPluginName() -{ - return "Process debugging plug-in for MacOSX"; -} - -const char * -ProcessMacOSX::GetShortPluginName() -{ - return GetPluginNameStatic(); -} - -uint32_t -ProcessMacOSX::GetPluginVersion() -{ - return 1; -} - -//---------------------------------------------------------------------- -// Process Control -//---------------------------------------------------------------------- -Error -ProcessMacOSX::DoLaunch -( - Module* module, - char const *argv[], - char const *envp[], - uint32_t flags, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - const char *working_dir -) -{ -// ::LogSetBitMask (PD_LOG_DEFAULT); -// ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD); -// ::LogSetLogFile ("/dev/stdout"); - - Error error; - ObjectFile * object_file = module->GetObjectFile(); - if (object_file) - { - ArchSpec arch_spec(module->GetArchitecture()); - - // Set our user ID to our process ID. - SetID (LaunchForDebug(argv[0], argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, eLaunchDefault, flags, error)); - } - else - { - // Set our user ID to an invalid process ID. - SetID (LLDB_INVALID_PROCESS_ID); - error.SetErrorToGenericError (); - error.SetErrorStringWithFormat("Failed to get object file from '%s' for arch %s.\n", - module->GetFileSpec().GetFilename().AsCString(), - module->GetArchitecture().GetArchitectureName()); - } - - // Return the process ID we have - return error; -} - -Error -ProcessMacOSX::DoAttachToProcessWithID (lldb::pid_t attach_pid) -{ - Error error; - - // Clear out and clean up from any current state - Clear(); - // HACK: require arch be set correctly at the target level until we can - // figure out a good way to determine the arch of what we are attaching to - m_arch_spec = m_target.GetArchitecture(); - - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS)); - if (attach_pid != LLDB_INVALID_PROCESS_ID) - { - SetID(attach_pid); - // Let ourselves know we are going to be using SBS if the correct flag bit is set... -#if defined (__arm__) - if (IsSBProcess(pid)) - m_flags |= eFlagsUsingSBS; -#endif - - if (Task().GetTaskPortForProcessID(error) == TASK_NULL) - { - if (log) - log->Printf ("error attaching to pid %i: %s", GetID(), error.AsCString()); - - } - else - { - Task().StartExceptionThread(error); - - if (error.Success()) - { - errno = 0; - if (::ptrace (PT_ATTACHEXC, GetID(), 0, 0) == 0) - { - m_flags.Set (eFlagsAttached); - // Sleep a bit to let the exception get received and set our process status - // to stopped. - ::usleep(250000); - - if (log) - log->Printf ("successfully attached to pid %d", GetID()); - return error; - } - else - { - error.SetErrorToErrno(); - if (log) - log->Printf ("error: failed to attach to pid %d", GetID()); - } - } - else - { - if (log) - log->Printf ("error: failed to start exception thread for pid %d: %s", GetID(), error.AsCString()); - } - - } - } - SetID (LLDB_INVALID_PROCESS_ID); - if (error.Success()) - error.SetErrorStringWithFormat ("failed to attach to pid %d", attach_pid); - return error; -} - -Error -ProcessMacOSX::WillLaunchOrAttach () -{ - return Error(); -} - - -Error -ProcessMacOSX::WillLaunch (Module* module) -{ - return WillLaunchOrAttach (); -} - -void -ProcessMacOSX::DidLaunchOrAttach () -{ - if (GetID() != LLDB_INVALID_PROCESS_ID) - { - Module * exe_module = GetTarget().GetExecutableModule ().get(); - assert (exe_module); - - // Install a signal handler so we can catch when our child process - // dies and set the exit status correctly. - - m_monitor_thread = Host::StartMonitoringChildProcess (Process::SetProcessExitStatus, NULL, GetID(), false); - } -} - -void -ProcessMacOSX::DidLaunch () -{ - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSX::DidLaunch()"); - DidLaunchOrAttach (); -} - -void -ProcessMacOSX::DidAttach () -{ - DidLaunchOrAttach (); -} - -Error -ProcessMacOSX::WillAttachToProcessWithID (lldb::pid_t pid) -{ - return WillLaunchOrAttach (); -} - -Error -ProcessMacOSX::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) -{ - return WillLaunchOrAttach (); -} - - -Error -ProcessMacOSX::DoResume () -{ - Error error; - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSX::Resume()"); - const StateType state = m_private_state.GetValue(); - - if (CanResume(state)) - { - error = PrivateResume(LLDB_INVALID_THREAD_ID); - } - else if (state == eStateRunning) - { - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "Resume() - task 0x%x is running, ignoring...", Task().GetTaskPort()); - } - else - { - error.SetErrorStringWithFormat("task 0x%x can't continue, ignoring...", Task().GetTaskPort()); - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "Resume() - task 0x%x can't continue, ignoring...", Task().GetTaskPort()); - } - return error; -} - -uint32_t -ProcessMacOSX::UpdateThreadListIfNeeded () -{ - // locker will keep a mutex locked until it goes out of scope - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_THREAD)); - if (log && log->GetMask().Test(PD_LOG_VERBOSE)) - log->Printf ("ProcessMacOSX::%s (pid = %4.4x)", __FUNCTION__, GetID()); - - const uint32_t stop_id = GetStopID(); - if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID()) - { - // Update the thread list's stop id immediately so we don't recurse into this function. - thread_array_t thread_list = NULL; - mach_msg_type_number_t thread_list_count = 0; - task_t task = Task().GetTaskPort(); - Error err(::task_threads (task, &thread_list, &thread_list_count), eErrorTypeMachKernel); - - if (log || err.Fail()) - err.PutToLog(log.get(), "::task_threads ( task = 0x%4.4x, thread_list => %p, thread_list_count => %u )", task, thread_list, thread_list_count); - - if (err.GetError() == KERN_SUCCESS && thread_list_count > 0) - { - ThreadList curr_thread_list (this); - curr_thread_list.SetStopID(stop_id); - - size_t idx; - // Iterator through the current thread list and see which threads - // we already have in our list (keep them), which ones we don't - // (add them), and which ones are not around anymore (remove them). - for (idx = 0; idx < thread_list_count; ++idx) - { - const lldb::tid_t tid = thread_list[idx]; - ThreadSP thread_sp(GetThreadList().FindThreadByID (tid, false)); - if (thread_sp.get() == NULL) - thread_sp.reset (new ThreadMacOSX (*this, tid)); - curr_thread_list.AddThread(thread_sp); - } - - m_thread_list = curr_thread_list; - - // Free the vm memory given to us by ::task_threads() - vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (lldb::tid_t)); - ::vm_deallocate (::mach_task_self(), - (vm_address_t)thread_list, - thread_list_size); - } - } - return GetThreadList().GetSize(false); -} - - -void -ProcessMacOSX::RefreshStateAfterStop () -{ - // If we are attaching, let our dynamic loader plug-in know so it can get - // an initial list of shared libraries. - - // We must be attaching if we don't already have a valid architecture - if (!m_arch_spec.IsValid()) - { - Module *exe_module = GetTarget().GetExecutableModule().get(); - if (exe_module) - m_arch_spec = exe_module->GetArchitecture(); - } - // Discover new threads: - UpdateThreadListIfNeeded (); - - // Let all threads recover from stopping and do any clean up based - // on the previous thread state (if any). - m_thread_list.RefreshStateAfterStop(); - - // Let each thread know of any exceptions - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS)); - task_t task = Task().GetTaskPort(); - size_t i; - for (i=0; i<m_exception_messages.size(); ++i) - { - // Let the thread list figure use the ProcessMacOSX to forward all exceptions - // on down to each thread. - if (m_exception_messages[i].state.task_port == task) - { - ThreadSP thread_sp(m_thread_list.FindThreadByID(m_exception_messages[i].state.thread_port)); - if (thread_sp.get()) - { - ThreadMacOSX *macosx_thread = (ThreadMacOSX *)thread_sp.get(); - macosx_thread->NotifyException (m_exception_messages[i].state); - } - } - if (log) - m_exception_messages[i].PutToLog(log.get()); - } - -} - -Error -ProcessMacOSX::DoHalt (bool &caused_stop) -{ - caused_stop = true; - return Signal (SIGSTOP); -} - -Error -ProcessMacOSX::WillDetach () -{ - Error error; - const StateType state = m_private_state.GetValue(); - - if (IsRunning(state)) - { - error.SetErrorToGenericError(); - error.SetErrorString("Process must be stopped in order to detach."); - } - return error; -} - -Error -ProcessMacOSX::DoSIGSTOP (bool clear_all_breakpoints) -{ - Error error; - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS)); - - if (log) - log->Printf ("ProcessMacOSX::DoSIGSTOP()"); - EventSP event_sp; - TimeValue timeout_time; - - StateType state = m_private_state.GetValue(); - - lldb::pid_t pid = GetID(); - - if (IsRunning(state)) - { - // If our process is running, we need to SIGSTOP it so we can detach. - if (log) - log->Printf ("ProcessMacOSX::DoDestroy() - kill (%i, SIGSTOP)", pid); - - // Send the SIGSTOP and wait a few seconds for it to stop - - // Pause the Private State Thread so it doesn't intercept the events we need to wait for. - PausePrivateStateThread(); - // I don't think this is right. Halt should just stop the process, and then whoever called halt should - // arrange whatever they need to with the thread plans. - - //m_thread_list.DiscardThreadPlans(); - - // First jettison all the current thread plans, since we want to make sure it - // really just stops. - - if (::kill (pid, SIGSTOP) == 0) - error.Clear(); - else - error.SetErrorToErrno(); - - if (error.Fail()) - error.PutToLog(log.get(), "::kill (pid = %i, SIGSTOP)", pid); - - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds(2); - - state = WaitForStateChangedEventsPrivate (&timeout_time, event_sp); - - // Resume the private state thread at this point. - ResumePrivateStateThread(); - - if (!StateIsStoppedState (state)) - { - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS); - if (log) - log->Printf("ProcessMacOSX::DoSIGSTOP() failed to stop after sending SIGSTOP"); - return error; - } - if (clear_all_breakpoints) - GetTarget().DisableAllBreakpoints(); - } - else if (!HasExited(state)) - { - if (clear_all_breakpoints) - GetTarget().DisableAllBreakpoints(); - -// const uint32_t num_threads = GetNumThreads(); -// for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) -// { -// Thread *thread = GetThreadAtIndex(thread_idx); -// thread->SetResumeState(eStateRunning); -// if (thread_idx == 0) -// thread->SetResumeSignal(SIGSTOP); -// } - - // Our process was stopped, so resume it and then SIGSTOP it so we can - // detach. - // But discard all the thread plans first, so we don't keep going because we - // are in mid-plan. - - // Pause the Private State Thread so it doesn't intercept the events we need to wait for. - PausePrivateStateThread(); - - m_thread_list.DiscardThreadPlans(); - - if (::kill (pid, SIGSTOP) == 0) - error.Clear(); - else - error.SetErrorToErrno(); - - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS); - if (log || error.Fail()) - error.PutToLog(log.get(), "ProcessMacOSX::DoSIGSTOP() ::kill (pid = %i, SIGSTOP)", pid); - - error = PrivateResume(LLDB_INVALID_THREAD_ID); - - // Wait a few seconds for our process to resume - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds(2); - state = WaitForStateChangedEventsPrivate (&timeout_time, event_sp); - - // Make sure the process resumed - if (StateIsStoppedState (state)) - { - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS); - if (log) - log->Printf ("ProcessMacOSX::DoSIGSTOP() couldn't resume process, state = %s", StateAsCString(state)); - error.SetErrorStringWithFormat("ProcessMacOSX::DoSIGSTOP() couldn't resume process, state = %s", StateAsCString(state)); - } - else - { - // Send the SIGSTOP and wait a few seconds for it to stop - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds(2); - state = WaitForStateChangedEventsPrivate (&timeout_time, event_sp); - if (!StateIsStoppedState (state)) - { - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS); - if (log) - log->Printf("ProcessMacOSX::DoSIGSTOP() failed to stop after sending SIGSTOP"); - error.SetErrorString("ProcessMacOSX::DoSIGSTOP() failed to stop after sending SIGSTOP"); - } - } - // Resume the private state thread at this point. - ResumePrivateStateThread(); - } - - return error; -} - -Error -ProcessMacOSX::DoDestroy () -{ - Error error; - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS)); - if (log) - log->Printf ("ProcessMacOSX::DoDestroy()"); - - error = DoSIGSTOP (true); - if (error.Success()) - { - StopSTDIOThread(true); - - if (log) - log->Printf ("ProcessMacOSX::DoDestroy() DoSIGSTOP succeeded"); - const StateType state = m_private_state.GetValue(); - // Scope for "locker" so we can reply to all of our exceptions (the SIGSTOP - // exception). - { - Mutex::Locker locker(m_exception_messages_mutex); - ReplyToAllExceptions(); - } - if (log) - log->Printf ("ProcessMacOSX::DoDestroy() replied to all exceptions"); - - // Shut down the exception thread and cleanup our exception remappings - Task().ShutDownExceptionThread(); - - if (log) - log->Printf ("ProcessMacOSX::DoDestroy() exception thread has been shutdown"); - - if (!HasExited(state)) - { - lldb::pid_t pid = GetID(); - - // Detach from our process while we are stopped. - errno = 0; - - // Detach from our process - ::ptrace (PT_KILL, pid, 0, 0); - - error.SetErrorToErrno(); - - if (log || error.Fail()) - error.PutToLog (log.get(), "::ptrace (PT_KILL, %u, 0, 0)", pid); - - // Resume our task and let the SIGKILL do its thing. The thread named - // "ProcessMacOSX::WaitForChildProcessToExit(void*)" will catch the - // process exiting, so we don't need to set our state to exited in this - // function. - Task().Resume(); - } - - // NULL our task out as we have already restored all exception ports - Task().Clear(); - - // Clear out any notion of the process we once were - Clear(); - } - return error; -} - -//------------------------------------------------------------------ -// Process Queries -//------------------------------------------------------------------ - -bool -ProcessMacOSX::IsAlive () -{ - return MachTask::IsValid (Task().GetTaskPort()); -} - -lldb::addr_t -ProcessMacOSX::GetImageInfoAddress() -{ - return Task().GetDYLDAllImageInfosAddress(); -} - -//------------------------------------------------------------------ -// Process Memory -//------------------------------------------------------------------ - -size_t -ProcessMacOSX::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error& error) -{ - return Task().ReadMemory(addr, buf, size, error); -} - -size_t -ProcessMacOSX::DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, Error& error) -{ - return Task().WriteMemory(addr, buf, size, error); -} - -lldb::addr_t -ProcessMacOSX::DoAllocateMemory (size_t size, uint32_t permissions, Error& error) -{ - return Task().AllocateMemory (size, permissions, error); -} - -Error -ProcessMacOSX::DoDeallocateMemory (lldb::addr_t ptr) -{ - return Task().DeallocateMemory (ptr); -} - -//------------------------------------------------------------------ -// Process STDIO -//------------------------------------------------------------------ - -size_t -ProcessMacOSX::GetSTDOUT (char *buf, size_t buf_size, Error &error) -{ - error.Clear(); - Mutex::Locker locker(m_stdio_mutex); - size_t bytes_available = m_stdout_data.size(); - if (bytes_available > 0) - { - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSX::%s (&%p[%u]) ...", __FUNCTION__, buf, buf_size); - if (bytes_available > buf_size) - { - memcpy(buf, m_stdout_data.c_str(), buf_size); - m_stdout_data.erase(0, buf_size); - bytes_available = buf_size; - } - else - { - memcpy(buf, m_stdout_data.c_str(), bytes_available); - m_stdout_data.clear(); - - //ResetEventBits(eBroadcastBitSTDOUT); - } - } - return bytes_available; -} - -size_t -ProcessMacOSX::GetSTDERR (char *buf, size_t buf_size, Error &error) -{ - error.Clear(); - return 0; -} - -size_t -ProcessMacOSX::PutSTDIN (const char *buf, size_t buf_size, Error &error) -{ - if (m_child_stdin == -1) - { - error.SetErrorString ("Invalid child stdin handle."); - } - else - { - ssize_t bytes_written = ::write (m_child_stdin, buf, buf_size); - if (bytes_written == -1) - error.SetErrorToErrno(); - else - { - error.Clear(); - return bytes_written; - } - } - return 0; -} - -Error -ProcessMacOSX::EnableBreakpoint (BreakpointSite *bp_site) -{ - Error error; - assert (bp_site != NULL); - const lldb::addr_t addr = bp_site->GetLoadAddress(); - const lldb::user_id_t site_id = bp_site->GetID(); - - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_BREAKPOINTS)); - if (log) - log->Printf ("ProcessMacOSX::EnableBreakpoint (site_id = %d) addr = 0x%8.8llx", site_id, (uint64_t)addr); - - if (bp_site->IsEnabled()) - { - if (log) - log->Printf ("ProcessMacOSX::EnableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS (already enabled)", site_id, (uint64_t)addr); - return error; - } - - if (bp_site->HardwarePreferred()) - { - // FIXME: This code doesn't make sense. Breakpoint sites don't really have single ThreadID's, since one site could be - // owned by a number of Locations, each with a different Thread ID. So either this should run over all the Locations and - // set it for all threads owned by those locations, or set it for all threads, and let the thread specific code sort it out. - -// ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(bp_site->GetThreadID()).get(); -// if (thread) -// { -// bp_site->SetHardwareIndex (thread->SetHardwareBreakpoint(bp_site)); -// if (bp_site->IsHardware()) -// { -// bp_site->SetEnabled(true); -// return error; -// } -// } - } - - // Just let lldb::Process::EnableSoftwareBreakpoint() handle everything... - return EnableSoftwareBreakpoint (bp_site); -} - -Error -ProcessMacOSX::DisableBreakpoint (BreakpointSite *bp_site) -{ - Error error; - assert (bp_site != NULL); - const lldb::addr_t addr = bp_site->GetLoadAddress(); - const lldb::user_id_t site_id = bp_site->GetID(); - - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_BREAKPOINTS)); - if (log) - log->Printf ("ProcessMacOSX::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx", site_id, (uint64_t)addr); - - if (bp_site->IsHardware()) - { - error.SetErrorString("hardware breakpoints are no supported"); - return error; - } - - // Just let lldb::Process::EnableSoftwareBreakpoint() handle everything... - return DisableSoftwareBreakpoint (bp_site); -} - -Error -ProcessMacOSX::EnableWatchpoint (WatchpointLocation *wp) -{ - Error error; - if (wp) - { - lldb::user_id_t watchID = wp->GetID(); - lldb::addr_t addr = wp->GetLoadAddress(); - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_WATCHPOINTS)); - if (log) - log->Printf ("ProcessMacOSX::EnableWatchpoint(watchID = %d)", watchID); - if (wp->IsEnabled()) - { - if (log) - log->Printf("ProcessMacOSX::EnableWatchpoint(watchID = %d) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr); - return error; - } - else - { - // Watchpoints aren't supported at present. - error.SetErrorString("Watchpoints aren't currently supported."); - } - } - return error; -} - -Error -ProcessMacOSX::DisableWatchpoint (WatchpointLocation *wp) -{ - Error error; - if (wp) - { - lldb::user_id_t watchID = wp->GetID(); - - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_WATCHPOINTS)); - - lldb::addr_t addr = wp->GetLoadAddress(); - if (log) - log->Printf ("ProcessMacOSX::DisableWatchpoint (watchID = %d) addr = 0x%8.8llx", watchID, (uint64_t)addr); - - if (wp->IsHardware()) - { - error.SetErrorString("Watchpoints aren't currently supported."); - } - // TODO: clear software watchpoints if we implement them - error.SetErrorToGenericError(); - } - else - { - error.SetErrorString("Watchpoint location argument was NULL."); - } - return error; -} - - -static ProcessMacOSX::CreateArchCalback -ArchCallbackMap(const ArchSpec& arch_spec, ProcessMacOSX::CreateArchCalback callback, bool add ) -{ - // We must wrap the "g_arch_map" file static in a function to avoid - // any global constructors so we don't get a build verification error - typedef std::multimap<ArchSpec, ProcessMacOSX::CreateArchCalback> ArchToProtocolMap; - static ArchToProtocolMap g_arch_map; - - if (add) - { - g_arch_map.insert(std::make_pair(arch_spec, callback)); - return callback; - } - else - { - ArchToProtocolMap::const_iterator pos = g_arch_map.find(arch_spec); - if (pos != g_arch_map.end()) - { - return pos->second; - } - } - return NULL; -} - -void -ProcessMacOSX::AddArchCreateCallback(const ArchSpec& arch_spec, CreateArchCalback callback) -{ - ArchCallbackMap (arch_spec, callback, true); -} - -ProcessMacOSX::CreateArchCalback -ProcessMacOSX::GetArchCreateCallback() -{ - return ArchCallbackMap (m_arch_spec, NULL, false); -} - -void -ProcessMacOSX::Clear() -{ - // Clear any cached thread list while the pid and task are still valid - - Task().Clear(); - // Now clear out all member variables - CloseChildFileDescriptors(); - - m_flags = eFlagsNone; - m_thread_list.Clear(); - { - Mutex::Locker locker(m_exception_messages_mutex); - m_exception_messages.clear(); - } - - if (IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) - { - Host::ThreadCancel (m_monitor_thread, NULL); - thread_result_t thread_result; - Host::ThreadJoin (m_monitor_thread, &thread_result, NULL); - m_monitor_thread = LLDB_INVALID_HOST_THREAD; - } - -} - -bool -ProcessMacOSX::StartSTDIOThread() -{ - if (IS_VALID_LLDB_HOST_THREAD(m_stdio_thread)) - return true; - - // If we created and own the child STDIO file handles, then we track the - // STDIO ourselves, else we let whomever owns these file handles track - // the IO themselves. - if (m_stdio_ours) - { - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSX::%s ( )", __FUNCTION__); - // Create the thread that watches for the child STDIO - m_stdio_thread = Host::ThreadCreate ("<lldb.process.process-macosx.stdio>", ProcessMacOSX::STDIOThread, this, NULL); - return IS_VALID_LLDB_HOST_THREAD(m_stdio_thread); - } - return false; -} - - -void -ProcessMacOSX::StopSTDIOThread(bool close_child_fds) -{ - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSX::%s ( )", __FUNCTION__); - // Stop the stdio thread - if (IS_VALID_LLDB_HOST_THREAD(m_stdio_thread)) - { - Host::ThreadCancel (m_stdio_thread, NULL); - thread_result_t result = NULL; - Host::ThreadJoin (m_stdio_thread, &result, NULL); - if (close_child_fds) - CloseChildFileDescriptors(); - else - { - // We may have given up control of these file handles, so just - // set them to invalid values so the STDIO thread can exit when - // we interrupt it with pthread_cancel... - m_child_stdin = -1; - m_child_stdout = -1; - m_child_stderr = -1; - } - } -} - - -void * -ProcessMacOSX::STDIOThread(void *arg) -{ - ProcessMacOSX *proc = (ProcessMacOSX*) arg; - - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS)); - if (log) - log->Printf ("ProcessMacOSX::%s (arg = %p) thread starting...", __FUNCTION__, arg); - - // We start use a base and more options so we can control if we - // are currently using a timeout on the mach_msg. We do this to get a - // bunch of related exceptions on our exception port so we can process - // then together. When we have multiple threads, we can get an exception - // per thread and they will come in consecutively. The main thread loop - // will start by calling mach_msg to without having the MACH_RCV_TIMEOUT - // flag set in the options, so we will wait forever for an exception on - // our exception port. After we get one exception, we then will use the - // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current - // exceptions for our process. After we have received the last pending - // exception, we will get a timeout which enables us to then notify - // our main thread that we have an exception bundle available. We then wait - // for the main thread to tell this exception thread to start trying to get - // exceptions messages again and we start again with a mach_msg read with - // infinite timeout. - Error err; - int stdout_fd = proc->GetStdoutFileDescriptor(); - int stderr_fd = proc->GetStderrFileDescriptor(); - if (stdout_fd == stderr_fd) - stderr_fd = -1; - - while (stdout_fd >= 0 || stderr_fd >= 0) - { - //::pthread_testcancel (); - - fd_set read_fds; - FD_ZERO (&read_fds); - if (stdout_fd >= 0) - FD_SET (stdout_fd, &read_fds); - if (stderr_fd >= 0) - FD_SET (stderr_fd, &read_fds); - int nfds = std::max<int>(stdout_fd, stderr_fd) + 1; - - int num_set_fds = select (nfds, &read_fds, NULL, NULL, NULL); - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS); - if (log) - log->Printf("select (nfds, &read_fds, NULL, NULL, NULL) => %d", num_set_fds); - - if (num_set_fds < 0) - { - int select_errno = errno; - if (log) - { - err.SetError (select_errno, eErrorTypePOSIX); - err.LogIfError(log.get(), "select (nfds, &read_fds, NULL, NULL, NULL) => %d", num_set_fds); - } - - switch (select_errno) - { - case EAGAIN: // The kernel was (perhaps temporarily) unable to allocate the requested number of file descriptors, or we have non-blocking IO - break; - case EBADF: // One of the descriptor sets specified an invalid descriptor. - return NULL; - break; - case EINTR: // A signal was delivered before the time limit expired and before any of the selected events occurred. - case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. - default: // Other unknown error - break; - } - } - else if (num_set_fds == 0) - { - } - else - { - char s[1024]; - s[sizeof(s)-1] = '\0'; // Ensure we have NULL termination - int bytes_read = 0; - if (stdout_fd >= 0 && FD_ISSET (stdout_fd, &read_fds)) - { - do - { - bytes_read = ::read (stdout_fd, s, sizeof(s)-1); - if (bytes_read < 0) - { - int read_errno = errno; - if (log) - log->Printf("read (stdout_fd, ) => %d errno: %d (%s)", bytes_read, read_errno, strerror(read_errno)); - } - else if (bytes_read == 0) - { - // EOF... - if (log) - log->Printf("read (stdout_fd, ) => %d (reached EOF for child STDOUT)", bytes_read); - stdout_fd = -1; - } - else if (bytes_read > 0) - { - proc->AppendSTDOUT(s, bytes_read); - } - - } while (bytes_read > 0); - } - - if (stderr_fd >= 0 && FD_ISSET (stderr_fd, &read_fds)) - { - do - { - bytes_read = ::read (stderr_fd, s, sizeof(s)-1); - if (bytes_read < 0) - { - int read_errno = errno; - if (log) - log->Printf("read (stderr_fd, ) => %d errno: %d (%s)", bytes_read, read_errno, strerror(read_errno)); - } - else if (bytes_read == 0) - { - // EOF... - if (log) - log->Printf("read (stderr_fd, ) => %d (reached EOF for child STDERR)", bytes_read); - stderr_fd = -1; - } - else if (bytes_read > 0) - { - proc->AppendSTDOUT(s, bytes_read); - } - - } while (bytes_read > 0); - } - } - } - - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS); - if (log) - log->Printf("ProcessMacOSX::%s (%p): thread exiting...", __FUNCTION__, arg); - - return NULL; -} - -Error -ProcessMacOSX::DoSignal (int signal) -{ - Error error; - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS)); - if (log) - log->Printf ("ProcessMacOSX::DoSignal (signal = %d)", signal); - if (::kill (GetID(), signal) != 0) - { - error.SetErrorToErrno(); - error.LogIfError(log.get(), "ProcessMacOSX::DoSignal (%d)", signal); - } - return error; -} - - -Error -ProcessMacOSX::DoDetach() -{ - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS)); - if (log) - log->Printf ("ProcessMacOSX::DoDetach()"); - - Error error (DoSIGSTOP (true)); - if (error.Success()) - { - CloseChildFileDescriptors (); - - // Scope for "locker" so we can reply to all of our exceptions (the SIGSTOP - // exception). - { - Mutex::Locker locker(m_exception_messages_mutex); - ReplyToAllExceptions(); - } - - // Shut down the exception thread and cleanup our exception remappings - Task().ShutDownExceptionThread(); - - lldb::pid_t pid = GetID(); - - // Detach from our process while we are stopped. - errno = 0; - - // Detach from our process - ::ptrace (PT_DETACH, pid, (caddr_t)1, 0); - - error.SetErrorToErrno(); - - if (log || error.Fail()) - error.PutToLog(log.get(), "::ptrace (PT_DETACH, %u, (caddr_t)1, 0)", pid); - - // Resume our task - Task().Resume(); - - // NULL our task out as we have already restored all exception ports - Task().Clear(); - - // Clear out any notion of the process we once were - Clear(); - - SetPrivateState (eStateDetached); - } - return error; -} - - - -Error -ProcessMacOSX::ReplyToAllExceptions() -{ - Error error; - Mutex::Locker locker(m_exception_messages_mutex); - if (m_exception_messages.empty() == false) - { - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS)); - - MachException::Message::iterator pos; - MachException::Message::iterator begin = m_exception_messages.begin(); - MachException::Message::iterator end = m_exception_messages.end(); - for (pos = begin; pos != end; ++pos) - { - int resume_signal = -1; - ThreadSP thread_sp = m_thread_list.FindThreadByID(pos->state.thread_port); - if (thread_sp.get()) - resume_signal = thread_sp->GetResumeSignal(); - if (log) - log->Printf ("Replying to exception %d, tid = 0x%4.4x, resume_signal = %i", std::distance(begin, pos), thread_sp->GetID(), resume_signal); - Error curr_error (pos->Reply (Task().GetTaskPort(), GetID(), resume_signal)); - - // Only report the first error - if (curr_error.Fail() && error.Success()) - error = curr_error; - - error.LogIfError(log.get(), "Error replying to exception"); - } - - // Erase all exception message as we should have used and replied - // to them all already. - m_exception_messages.clear(); - } - return error; -} - - -Error -ProcessMacOSX::PrivateResume (lldb::tid_t tid) -{ - - Mutex::Locker locker(m_exception_messages_mutex); - Error error (ReplyToAllExceptions()); - - // Let the thread prepare to resume and see if any threads want us to - // step over a breakpoint instruction (ProcessWillResume will modify - // the value of stepOverBreakInstruction). - //StateType process_state = m_thread_list.ProcessWillResume(this); - - // Set our state accordingly - SetPrivateState (eStateRunning); - - // Now resume our task. - error = Task().Resume(); - return error; -} - -// Called by the exception thread when an exception has been received from -// our process. The exception message is completely filled and the exception -// data has already been copied. -void -ProcessMacOSX::ExceptionMessageReceived (const MachException::Message& exceptionMessage) -{ - Mutex::Locker locker(m_exception_messages_mutex); - - if (m_exception_messages.empty()) - Task().Suspend(); - - ProcessMacOSXLog::LogIf (PD_LOG_EXCEPTIONS, "ProcessMacOSX::ExceptionMessageReceived ( )"); - - // Use a locker to automatically unlock our mutex in case of exceptions - // Add the exception to our internal exception stack - m_exception_messages.push_back(exceptionMessage); -} - - -//bool -//ProcessMacOSX::GetProcessInfo (struct kinfo_proc* proc_info) -//{ -// int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, GetID() }; -// size_t buf_size = sizeof(struct kinfo_proc); -// -// if (::sysctl (mib, (unsigned)(sizeof(mib)/sizeof(int)), &proc_info, &buf_size, NULL, 0) == 0) -// return buf_size > 0; -// -// return false; -//} -// -// -void -ProcessMacOSX::ExceptionMessageBundleComplete() -{ - // We have a complete bundle of exceptions for our child process. - Mutex::Locker locker(m_exception_messages_mutex); - ProcessMacOSXLog::LogIf (PD_LOG_EXCEPTIONS, "%s: %d exception messages.", __PRETTY_FUNCTION__, m_exception_messages.size()); - if (!m_exception_messages.empty()) - { - SetPrivateState (eStateStopped); - } - else - { - ProcessMacOSXLog::LogIf (PD_LOG_EXCEPTIONS, "%s empty exception messages bundle.", __PRETTY_FUNCTION__, m_exception_messages.size()); - } -} - -bool -ProcessMacOSX::ReleaseChildFileDescriptors ( int *stdin_fileno, int *stdout_fileno, int *stderr_fileno ) -{ - if (stdin_fileno) - *stdin_fileno = m_child_stdin; - if (stdout_fileno) - *stdout_fileno = m_child_stdout; - if (stderr_fileno) - *stderr_fileno = m_child_stderr; - // Stop the stdio thread if we have one, but don't have it close the child - // file descriptors since we are giving control of these descriptors to the - // caller - bool close_child_fds = false; - StopSTDIOThread(close_child_fds); - return true; -} - -void -ProcessMacOSX::AppendSTDOUT (const char* s, size_t len) -{ - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSX::%s (<%d> %s) ...", __FUNCTION__, len, s); - Mutex::Locker locker(m_stdio_mutex); - m_stdout_data.append(s, len); - - // FIXME: Make a real data object for this and put it out. - BroadcastEventIfUnique (eBroadcastBitSTDOUT); -} - -lldb::pid_t -ProcessMacOSX::LaunchForDebug -( - const char *path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - PDLaunchType launch_type, - uint32_t flags, - Error &launch_err) -{ - // Clear out and clean up from any current state - Clear(); - - m_arch_spec = arch_spec; - - if (launch_type == eLaunchDefault) - launch_type = eLaunchPosixSpawn; - - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS)); - if (log) - log->Printf ("%s( path = '%s', argv = %p, envp = %p, launch_type = %u, flags = %x )", __FUNCTION__, path, argv, envp, launch_type, flags); - - // Fork a child process for debugging - SetPrivateState (eStateLaunching); - switch (launch_type) - { - case eLaunchForkExec: - SetID(ProcessMacOSX::ForkChildForPTraceDebugging(path, argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, this, launch_err)); - break; - - case eLaunchPosixSpawn: - SetID(ProcessMacOSX::PosixSpawnChildForPTraceDebugging(path, argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, this, flags & eLaunchFlagDisableASLR ? 1 : 0, launch_err)); - break; - -#if defined (__arm__) - - case eLaunchSpringBoard: - { - const char *app_ext = strstr(path, ".app"); - if (app_ext != NULL) - { - std::string app_bundle_path(path, app_ext + strlen(".app")); - return SBLaunchForDebug (app_bundle_path.c_str(), argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, launch_err); - } - } - break; - -#endif - - default: - // Invalid launch - launch_err.SetErrorToGenericError (); - return LLDB_INVALID_PROCESS_ID; - } - - lldb::pid_t pid = GetID(); - - if (pid == LLDB_INVALID_PROCESS_ID) - { - // If we don't have a valid process ID and no one has set the error, - // then return a generic error - if (launch_err.Success()) - launch_err.SetErrorToGenericError (); - } - else - { - // Make sure we can get our task port before going any further - Task().GetTaskPortForProcessID (launch_err); - - // If that goes well then kick off our exception thread - if (launch_err.Success()) - Task().StartExceptionThread(launch_err); - - if (launch_err.Success()) - { - //m_path = path; -// size_t i; -// if (argv) -// { -// char const *arg; -// for (i=0; (arg = argv[i]) != NULL; i++) -// m_args.push_back(arg); -// } - - StartSTDIOThread(); - - if (launch_type == eLaunchPosixSpawn) - { - errno = 0; - if (::ptrace (PT_ATTACHEXC, pid, 0, 0) == 0) - launch_err.Clear(); - else - launch_err.SetErrorToErrno(); - - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS); - if (launch_err.Fail() || log) - launch_err.PutToLog(log.get(), "::ptrace (PT_ATTACHEXC, pid = %i, 0, 0 )", pid); - - if (launch_err.Success()) - m_flags.Set (eFlagsAttached); - else - SetPrivateState (eStateExited); - } - else - { - launch_err.Clear(); - } - } - else - { - // We were able to launch the process, but not get its task port - // so now we need to make it sleep with da fishes. - SetID(LLDB_INVALID_PROCESS_ID); - ::ptrace (PT_KILL, pid, 0, 0 ); - ::kill (pid, SIGCONT); - pid = LLDB_INVALID_PROCESS_ID; - } - - } - return pid; -} - -lldb::pid_t -ProcessMacOSX::PosixSpawnChildForPTraceDebugging -( - const char *path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - ProcessMacOSX* process, - int disable_aslr, - Error &err -) -{ - posix_spawnattr_t attr; - short flags; - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS)); - - Error local_err; // Errors that don't affect the spawning. - if (log) - log->Printf ("%s ( path='%s', argv=%p, envp=%p, process )", __FUNCTION__, path, argv, envp); - err.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); - if (err.Fail() || log) - err.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )"); - if (err.Fail()) - return LLDB_INVALID_PROCESS_ID; - - flags = POSIX_SPAWN_START_SUSPENDED; - if (disable_aslr) - flags |= _POSIX_SPAWN_DISABLE_ASLR; - - err.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX); - if (err.Fail() || log) - err.PutToLog(log.get(), "::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED%s )", disable_aslr ? " | _POSIX_SPAWN_DISABLE_ASLR" : ""); - if (err.Fail()) - return LLDB_INVALID_PROCESS_ID; - -#if !defined(__arm__) - - // We don't need to do this for ARM, and we really shouldn't now that we - // have multiple CPU subtypes and no posix_spawnattr call that allows us - // to set which CPU subtype to launch... - cpu_type_t cpu = arch_spec.GetMachOCPUType(); - if (cpu != 0 && cpu != UINT32_MAX && cpu != LLDB_INVALID_CPUTYPE) - { - size_t ocount = 0; - err.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX); - if (err.Fail() || log) - err.PutToLog(log.get(), "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %zu )", cpu, ocount); - - if (err.Fail() != 0 || ocount != 1) - return LLDB_INVALID_PROCESS_ID; - } - -#endif - - lldb_utility::PseudoTerminal pty; - - posix_spawn_file_actions_t file_actions; - err.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); - int file_actions_valid = err.Success(); - if (!file_actions_valid || log) - err.PutToLog(log.get(), "::posix_spawn_file_actions_init ( &file_actions )"); - Error stdio_err; - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - if (file_actions_valid) - { - // If the user specified any STDIO files, then use those - if (stdin_path || stdout_path || stderr_path) - { - process->SetSTDIOIsOurs(false); - if (stderr_path != NULL && stderr_path[0]) - { - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDERR_FILENO, stderr_path, O_RDWR, 0), eErrorTypePOSIX); - if (stdio_err.Fail() || log) - stdio_err.PutToLog(log.get(), "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDERR_FILENO, path = '%s', oflag = O_RDWR, mode = 0 )", stderr_path); - } - - if (stdin_path != NULL && stdin_path[0]) - { - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDIN_FILENO, stdin_path, O_RDONLY, 0), eErrorTypePOSIX); - if (stdio_err.Fail() || log) - stdio_err.PutToLog(log.get(), "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDIN_FILENO, path = '%s', oflag = O_RDONLY, mode = 0 )", stdin_path); - } - - if (stdout_path != NULL && stdout_path[0]) - { - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDOUT_FILENO, stdout_path, O_WRONLY, 0), eErrorTypePOSIX); - if (stdio_err.Fail() || log) - stdio_err.PutToLog(log.get(), "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDOUT_FILENO, path = '%s', oflag = O_WRONLY, mode = 0 )", stdout_path); - } - } - else - { - // The user did not specify any STDIO files, use a pseudo terminal. - // Callers can then access the file handles using the - // ProcessMacOSX::ReleaseChildFileDescriptors() function, otherwise - // this class will spawn a thread that tracks STDIO and buffers it. - process->SetSTDIOIsOurs(true); - char error_str[1024]; - if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str))) - { - const char* slave_name = pty.GetSlaveName(error_str, sizeof(error_str)); - if (slave_name == NULL) - slave_name = "/dev/null"; - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDERR_FILENO, slave_name, O_RDWR|O_NOCTTY, 0), eErrorTypePOSIX); - if (stdio_err.Fail() || log) - stdio_err.PutToLog(log.get(), "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDERR_FILENO, path = '%s', oflag = O_RDWR|O_NOCTTY, mode = 0 )", slave_name); - - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDIN_FILENO, slave_name, O_RDONLY|O_NOCTTY, 0), eErrorTypePOSIX); - if (stdio_err.Fail() || log) - stdio_err.PutToLog(log.get(), "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDIN_FILENO, path = '%s', oflag = O_RDONLY|O_NOCTTY, mode = 0 )", slave_name); - - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDOUT_FILENO, slave_name, O_WRONLY|O_NOCTTY, 0), eErrorTypePOSIX); - if (stdio_err.Fail() || log) - stdio_err.PutToLog(log.get(), "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDOUT_FILENO, path = '%s', oflag = O_WRONLY|O_NOCTTY, mode = 0 )", slave_name); - } - else - { - if (error_str[0]) - stdio_err.SetErrorString(error_str); - else - stdio_err.SetErrorString("Unable to open master side of pty for inferior."); - } - - } - err.SetError( ::posix_spawnp (&pid, path, &file_actions, &attr, (char * const*)argv, (char * const*)envp), eErrorTypePOSIX); - if (err.Fail() || log) - err.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", pid, path, &file_actions, &attr, argv, envp); - - if (stdio_err.Success()) - { - // If we have a valid process and we created the STDIO file handles, - // then remember them on our process class so we can spawn a STDIO - // thread and close them when we are done with them. - if (process != NULL && process->STDIOIsOurs()) - { - int master_fd = pty.ReleaseMasterFileDescriptor (); - process->SetChildFileDescriptors (master_fd, master_fd, master_fd); - } - } - } - else - { - err.SetError( ::posix_spawnp (&pid, path, NULL, &attr, (char * const*)argv, (char * const*)envp), eErrorTypePOSIX); - if (err.Fail() || log) - err.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", pid, path, NULL, &attr, argv, envp); - } - - ::posix_spawnattr_destroy (&attr); - - // We have seen some cases where posix_spawnp was returning a valid - // looking pid even when an error was returned, so clear it out - if (err.Fail()) - pid = LLDB_INVALID_PROCESS_ID; - - if (file_actions_valid) - { - local_err.SetError( ::posix_spawn_file_actions_destroy (&file_actions), eErrorTypePOSIX); - if (local_err.Fail() || log) - local_err.PutToLog(log.get(), "::posix_spawn_file_actions_destroy ( &file_actions )"); - } - - return pid; -} - -lldb::pid_t -ProcessMacOSX::ForkChildForPTraceDebugging -( - const char *path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - ProcessMacOSX* process, - Error &launch_err -) -{ - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - - if (stdin_path || stdout_path || stderr_path) - { - assert(!"TODO: ForkChildForPTraceDebugging doesn't currently support fork/exec with user file handles..."); - } - else - { - - // Use a fork that ties the child process's stdin/out/err to a pseudo - // terminal so we can read it in our ProcessMacOSX::STDIOThread - // as unbuffered io. - lldb_utility::PseudoTerminal pty; - char error_str[1024]; - pid = pty.Fork(error_str, sizeof(error_str)); - - if (pid < 0) - { - launch_err.SetErrorString (error_str); - //-------------------------------------------------------------- - // Error during fork. - //-------------------------------------------------------------- - return pid; - } - else if (pid == 0) - { - //-------------------------------------------------------------- - // Child process - //-------------------------------------------------------------- - ::ptrace (PT_TRACE_ME, 0, 0, 0); // Debug this process - ::ptrace (PT_SIGEXC, 0, 0, 0); // Get BSD signals as mach exceptions - - // If our parent is setgid, lets make sure we don't inherit those - // extra powers due to nepotism. - ::setgid (getgid ()); - - // Let the child have its own process group. We need to execute - // this call in both the child and parent to avoid a race condition - // between the two processes. - ::setpgid (0, 0); // Set the child process group to match its pid - - // Sleep a bit to before the exec call - ::sleep (1); - - // Turn this process into - ::execv (path, (char * const *)argv); - // Exit with error code. Child process should have taken - // over in above exec call and if the exec fails it will - // exit the child process below. - ::exit (127); - } - else - { - //-------------------------------------------------------------- - // Parent process - //-------------------------------------------------------------- - // Let the child have its own process group. We need to execute - // this call in both the child and parent to avoid a race condition - // between the two processes. - ::setpgid (pid, pid); // Set the child process group to match its pid - - if (process != NULL) - { - // Release our master pty file descriptor so the pty class doesn't - // close it and so we can continue to use it in our STDIO thread - int master_fd = pty.ReleaseMasterFileDescriptor (); - process->SetChildFileDescriptors (master_fd, master_fd, master_fd); - } - } - } - return pid; -} - -#if defined (__arm__) - -lldb::pid_t -ProcessMacOSX::SBLaunchForDebug -( - const char *path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - Error &launch_err -) -{ - // Clear out and clean up from any current state - Clear(); - - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path); - - // Fork a child process for debugging - SetState(eStateLaunching); - m_pid = ProcessMacOSX::SBLaunchForDebug(path, argv, envp, this, launch_err); - if (m_pid != 0) - { - m_flags |= eFlagsUsingSBS; - //m_path = path; -// size_t i; -// char const *arg; -// for (i=0; (arg = argv[i]) != NULL; i++) -// m_args.push_back(arg); - Task().StartExceptionThread(); - StartSTDIOThread(); - int err = ptrace (PT_ATTACHEXC, m_pid, 0, 0); - if (err == 0) - { - m_flags |= eFlagsAttached; - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "successfully attached to pid %d", m_pid); - } - else - { - SetState (eStateExited); - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "error: failed to attach to pid %d", m_pid); - } - } - return m_pid; -} - -#include <servers/bootstrap.h> -#include "CFBundle.h" -#include "CFData.h" -#include "CFString.h" - -lldb::pid_t -ProcessMacOSX::SBLaunchForDebug -( - const char *app_bundle_path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - ProcessMacOSX* process, - Error &launch_err -) -{ - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s( '%s', argv, %p)", __FUNCTION__, app_bundle_path, process); - CFAllocatorRef alloc = kCFAllocatorDefault; - if (argv[0] == NULL) - return LLDB_INVALID_PROCESS_ID; - - size_t argc = 0; - // Count the number of arguments - while (argv[argc] != NULL) - argc++; - - // Enumerate the arguments - size_t first_launch_arg_idx = 1; - CFReleaser<CFMutableArrayRef> launch_argv; - - if (argv[first_launch_arg_idx]) - { - size_t launch_argc = argc > 0 ? argc - 1 : 0; - launch_argv.reset (::CFArrayCreateMutable (alloc, launch_argc, &kCFTypeArrayCallBacks)); - size_t i; - char const *arg; - CFString launch_arg; - for (i=first_launch_arg_idx; (i < argc) && ((arg = argv[i]) != NULL); i++) - { - launch_arg.reset(::CFStringCreateWithCString (alloc, arg, kCFStringEncodingUTF8)); - if (launch_arg.get() != NULL) - CFArrayAppendValue(launch_argv.get(), launch_arg.get()); - else - break; - } - } - - // Next fill in the arguments dictionary. Note, the envp array is of the form - // Variable=value but SpringBoard wants a CF dictionary. So we have to convert - // this here. - - CFReleaser<CFMutableDictionaryRef> launch_envp; - - if (envp[0]) - { - launch_envp.reset(::CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); - const char *value; - int name_len; - CFString name_string, value_string; - - for (int i = 0; envp[i] != NULL; i++) - { - value = strstr (envp[i], "="); - - // If the name field is empty or there's no =, skip it. Somebody's messing with us. - if (value == NULL || value == envp[i]) - continue; - - name_len = value - envp[i]; - - // Now move value over the "=" - value++; - - name_string.reset(::CFStringCreateWithBytes(alloc, (const UInt8 *) envp[i], name_len, kCFStringEncodingUTF8, false)); - value_string.reset(::CFStringCreateWithCString(alloc, value, kCFStringEncodingUTF8)); - CFDictionarySetValue (launch_envp.get(), name_string.get(), value_string.get()); - } - } - - CFString stdout_cf_path; - CFString stderr_cf_path; - PseudoTerminal pty; - - if (stdin_path || stdout_path || stderr_path) - { - process->SetSTDIOIsOurs(false); - if (stdout_path) - stdout_cf_path.SetFileSystemRepresentation (stdout_path); - if (stderr_path) - stderr_cf_path.SetFileSystemRepresentation (stderr_path); - } - else - { - process->SetSTDIOIsOurs(true); - PseudoTerminal::Error pty_err = pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY); - if (pty_err == PseudoTerminal::success) - { - const char* slave_name = pty.SlaveName(); - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() successfully opened master pty, slave is %s", __FUNCTION__, slave_name); - if (slave_name && slave_name[0]) - { - ::chmod (slave_name, S_IRWXU | S_IRWXG | S_IRWXO); - stdout_cf_path.SetFileSystemRepresentation (slave_name); - stderr_cf_path.(stdout_cf_path); - } - } - } - - if (stdout_cf_path.get() == NULL) - stdout_cf_path.SetFileSystemRepresentation ("/dev/null"); - if (stderr_cf_path.get() == NULL) - stderr_cf_path.SetFileSystemRepresentation ("/dev/null"); - - CFBundle bundle(app_bundle_path); - CFStringRef bundleIDCFStr = bundle.GetIdentifier(); - std::string bundleID; - if (CFString::UTF8(bundleIDCFStr, bundleID) == NULL) - { - struct stat app_bundle_stat; - if (::stat (app_bundle_path, &app_bundle_stat) < 0) - { - launch_err.SetError(errno, eErrorTypePOSIX); - launch_err.SetErrorStringWithFormat("%s: \"%s\".\n", launch_err.AsString(), app_bundle_path); - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() error: %s", __FUNCTION__, launch_err.AsCString()); - } - else - { - launch_err.SetError(-1, eErrorTypeGeneric); - launch_err.SetErrorStringWithFormat("Failed to extract CFBundleIdentifier from %s.\n", app_bundle_path); - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() error: failed to extract CFBundleIdentifier from '%s'", __FUNCTION__, app_bundle_path); - } - return LLDB_INVALID_PROCESS_ID; - } - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() extracted CFBundleIdentifier: %s", __FUNCTION__, bundleID.c_str()); - - - CFData argv_data(NULL); - - if (launch_argv.get()) - { - if (argv_data.Serialize(launch_argv.get(), kCFPropertyListBinaryFormat_v1_0) == NULL) - { - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() error: failed to serialize launch arg array...", __FUNCTION__); - return LLDB_INVALID_PROCESS_ID; - } - } - - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() serialized launch arg array", __FUNCTION__); - - // Find SpringBoard - SBSApplicationLaunchError sbs_error = 0; - sbs_error = SBSLaunchApplication ( bundleIDCFStr, - (CFURLRef)NULL, // openURL - launch_argv.get(), - launch_envp.get(), // CFDictionaryRef environment - stdout_cf_path.get(), - stderr_cf_path.get(), - SBSApplicationLaunchWaitForDebugger | SBSApplicationLaunchUnlockDevice); - - - launch_err.SetError(sbs_error, eErrorTypeSpringBoard); - - if (sbs_error == SBSApplicationLaunchErrorSuccess) - { - static const useconds_t pid_poll_interval = 200000; - static const useconds_t pid_poll_timeout = 30000000; - - useconds_t pid_poll_total = 0; - - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - Boolean pid_found = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &pid); - // Poll until the process is running, as long as we are getting valid responses and the timeout hasn't expired - // A return PID of 0 means the process is not running, which may be because it hasn't been (asynchronously) started - // yet, or that it died very quickly (if you weren't using waitForDebugger). - while (!pid_found && pid_poll_total < pid_poll_timeout) - { - usleep (pid_poll_interval); - pid_poll_total += pid_poll_interval; - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() polling Springboard for pid for %s...", __FUNCTION__, bundleID.c_str()); - pid_found = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &pid); - } - - if (pid_found) - { - // If we have a valid process and we created the STDIO file handles, - // then remember them on our process class so we can spawn a STDIO - // thread and close them when we are done with them. - if (process != NULL && process->STDIOIsOurs()) - { - // Release our master pty file descriptor so the pty class doesn't - // close it and so we can continue to use it in our STDIO thread - int master_fd = pty.ReleaseMasterFD(); - process->SetChildFileDescriptors(master_fd, master_fd, master_fd); - } - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() => pid = %4.4x", __FUNCTION__, pid); - } - else - { - LogError("failed to lookup the process ID for CFBundleIdentifier %s.", bundleID.c_str()); - } - return pid; - } - - LogError("unable to launch the application with CFBundleIdentifier '%s' sbs_error = %u", bundleID.c_str(), sbs_error); - return LLDB_INVALID_PROCESS_ID; -} - -#endif // #if defined (__arm__) - - -#include "MachThreadContext_x86_64.h" -#include "MachThreadContext_i386.h" -#include "MachThreadContext_arm.h" - -void -ProcessMacOSX::Initialize() -{ - static bool g_initialized = false; - - if (g_initialized == false) - { - g_initialized = true; - - MachThreadContext_x86_64::Initialize(); - MachThreadContext_i386::Initialize(); - MachThreadContext_arm::Initialize(); - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); - - Log::Callbacks log_callbacks = { - ProcessMacOSXLog::DisableLog, - ProcessMacOSXLog::EnableLog, - ProcessMacOSXLog::ListLogCategories - }; - - Log::RegisterLogChannel (ProcessMacOSX::GetPluginNameStatic(), log_callbacks); - - - } -} - -//uint32_t -//ProcessMacOSX::ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids) -//{ -// return Host::ListProcessesMatchingName (name, matches, pids); -//} - - diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h deleted file mode 100644 index 1267ad5af89..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h +++ /dev/null @@ -1,480 +0,0 @@ -//===-- ProcessMacOSX.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_MacOSXProcess_H_ -#define liblldb_MacOSXProcess_H_ - -// C Includes - -// C++ Includes -#include <list> - -// Other libraries and framework includes -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/ThreadSafeValue.h" -#include "lldb/Core/StringList.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" - -// Project includes -#include "MacOSX/MachTask.h" -#include "MacOSX/MachException.h" - -typedef enum PDLaunch -{ - eLaunchDefault = 0, - eLaunchPosixSpawn, - eLaunchForkExec, -#if defined (__arm__) - eLaunchSpringBoard, -#endif - kNumPDLaunchTypes -} PDLaunchType; - - - -class ThreadMacOSX; -class MachThreadContext; - -class ProcessMacOSX : - public lldb_private::Process -{ -public: - friend class ThreadMacOSX; - friend class MachTask; - - typedef MachThreadContext* (*CreateArchCalback) (const lldb_private::ArchSpec &arch_spec, ThreadMacOSX &thread); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - static Process* - CreateInstance (lldb_private::Target& target, lldb_private::Listener &listener); - - static void - Initialize(); - - static void - Terminate(); - - static const char * - GetPluginNameStatic(); - - static const char * - GetPluginDescriptionStatic(); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ProcessMacOSX(lldb_private::Target& target, lldb_private::Listener &listener); - - virtual - ~ProcessMacOSX(); - - //------------------------------------------------------------------ - // Check if a given Process - //------------------------------------------------------------------ - virtual bool - CanDebug (lldb_private::Target &target, - bool plugin_specified_by_name); - - //------------------------------------------------------------------ - // Creating a new process, or attaching to an existing one - //------------------------------------------------------------------ - virtual lldb_private::Error - WillLaunch (lldb_private::Module* module); - - virtual lldb_private::Error - DoLaunch (lldb_private::Module* module, - char const *argv[], // Can be NULL - char const *envp[], // Can be NULL - uint32_t launch_flags, - const char *stdin_path, // Can be NULL - const char *stdout_path, // Can be NULL - const char *stderr_path, // Can be NULL - const char *working_dir); // Can be NULL - - virtual void - DidLaunch (); - - virtual lldb_private::Error - WillAttachToProcessWithID (lldb::pid_t pid); - - virtual lldb_private::Error - WillAttachToProcessWithName (const char *process_name, bool wait_for_launch); - - virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid); - - virtual void - DidAttach (); - -// virtual uint32_t -// ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids); - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - virtual const char * - GetPluginName(); - - virtual const char * - GetShortPluginName(); - - virtual uint32_t - GetPluginVersion(); - - //------------------------------------------------------------------ - // Process Control - //------------------------------------------------------------------ - virtual lldb_private::Error - DoResume (); - - virtual lldb_private::Error - DoHalt (bool &caused_stop); - - virtual lldb_private::Error - WillDetach (); - - virtual lldb_private::Error - DoDetach (); - - virtual lldb_private::Error - DoSignal (int signal); - - virtual lldb_private::Error - DoDestroy (); - - virtual void - RefreshStateAfterStop(); - - //------------------------------------------------------------------ - // Process Queries - //------------------------------------------------------------------ - virtual bool - IsAlive (); - - virtual lldb::addr_t - GetImageInfoAddress(); - - //------------------------------------------------------------------ - // Process Memory - //------------------------------------------------------------------ - virtual size_t - DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error); - - virtual size_t - DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error); - - virtual lldb::addr_t - DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error); - - virtual lldb_private::Error - DoDeallocateMemory (lldb::addr_t ptr); - - //------------------------------------------------------------------ - // Process STDIO - //------------------------------------------------------------------ - virtual size_t - GetSTDOUT (char *buf, size_t buf_size, lldb_private::Error &error); - - virtual size_t - GetSTDERR (char *buf, size_t buf_size, lldb_private::Error &error); - - virtual size_t - PutSTDIN (const char *buf, size_t buf_size, lldb_private::Error &error); - - //---------------------------------------------------------------------- - // Process Breakpoints - //---------------------------------------------------------------------- - virtual lldb_private::Error - EnableBreakpoint (lldb_private::BreakpointSite *bp_site); - - virtual lldb_private::Error - DisableBreakpoint (lldb_private::BreakpointSite *bp_site); - - //---------------------------------------------------------------------- - // Process Watchpoints - //---------------------------------------------------------------------- - virtual lldb_private::Error - EnableWatchpoint (lldb_private::WatchpointLocation *wp_loc); - - virtual lldb_private::Error - DisableWatchpoint (lldb_private::WatchpointLocation *wp_loc); - - static void - AddArchCreateCallback(const lldb_private::ArchSpec& arch_spec, - ProcessMacOSX::CreateArchCalback callback); - -protected: - - bool m_stdio_ours; // True if we created and own the child STDIO file handles, false if they were supplied to us and owned by someone else - int m_child_stdin; - int m_child_stdout; - int m_child_stderr; - MachTask m_task; // The mach task for this process - lldb_private::Flags m_flags; // Process specific flags (see eFlags enums) - lldb::thread_t m_stdio_thread; // Thread ID for the thread that watches for child process stdio - lldb::thread_t m_monitor_thread; // Thread ID for the thread that watches for child process stdio - lldb_private::Mutex m_stdio_mutex; // Multithreaded protection for stdio - std::string m_stdout_data; - MachException::Message::collection m_exception_messages; // A collection of exception messages caught when listening to the exception port - lldb_private::Mutex m_exception_messages_mutex; // Multithreaded protection for m_exception_messages - lldb_private::ArchSpec m_arch_spec; - - //---------------------------------------------------------------------- - // Child process control - //---------------------------------------------------------------------- - lldb::pid_t - LaunchForDebug (const char *path, - char const *argv[], - char const *envp[], - lldb_private::ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - PDLaunchType launch_type, - uint32_t flags, - lldb_private::Error &launch_err); - - static lldb::pid_t - ForkChildForPTraceDebugging (const char *path, - char const *argv[], - char const *envp[], - lldb_private::ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - ProcessMacOSX* process, - lldb_private::Error &launch_err); - - static lldb::pid_t - PosixSpawnChildForPTraceDebugging (const char *path, - char const *argv[], - char const *envp[], - lldb_private::ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - ProcessMacOSX* process, - int disable_aslr, - lldb_private::Error &launch_err); - -#if defined (__arm__) - lldb::pid_t - SBLaunchForDebug (const char *path, - char const *argv[], - char const *envp[], - lldb_private::ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - lldb_private::Error &launch_err); - - static lldb::pid_t - SBLaunchForDebug (const char *path, - char const *argv[], - char const *envp[], - lldb_private::ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - ProcessMacOSX* process, - lldb_private::Error &launch_err); -#endif - - //---------------------------------------------------------------------- - // Exception thread functions - //---------------------------------------------------------------------- - bool - StartSTDIOThread (); - - void - StopSTDIOThread (bool close_child_fds); - - static void * - STDIOThread (void *arg); - - void - ExceptionMessageReceived (const MachException::Message& exceptionMessage); - - void - ExceptionMessageBundleComplete (); - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - bool - ProcessIDIsValid ( ) const; - - MachTask& - Task() { return m_task; } - - const MachTask& - Task() const { return m_task; } - - bool - IsRunning ( lldb::StateType state ) - { - return state == lldb::eStateRunning || IsStepping(state); - } - - bool - IsStepping ( lldb::StateType state) - { - return state == lldb::eStateStepping; - } - bool - CanResume ( lldb::StateType state) - { - return state == lldb::eStateStopped; - } - - bool - HasExited (lldb::StateType state) - { - return state == lldb::eStateExited; - } - - void - SetChildFileDescriptors (int stdin_fileno, int stdout_fileno, int stderr_fileno) - { - m_child_stdin = stdin_fileno; - m_child_stdout = stdout_fileno; - m_child_stderr = stderr_fileno; - } - - int - GetStdinFileDescriptor () const - { - return m_child_stdin; - } - - int - GetStdoutFileDescriptor () const - { - return m_child_stdout; - } - int - GetStderrFileDescriptor () const - { - return m_child_stderr; - } - bool - ReleaseChildFileDescriptors ( int *stdin_fileno, int *stdout_fileno, int *stderr_fileno ); - - void - AppendSTDOUT (const char* s, size_t len); - - void - CloseChildFileDescriptors () - { - if (m_child_stdin >= 0) - { - ::close (m_child_stdin); - m_child_stdin = -1; - } - if (m_child_stdout >= 0) - { - ::close (m_child_stdout); - m_child_stdout = -1; - } - if (m_child_stderr >= 0) - { - ::close (m_child_stderr); - m_child_stderr = -1; - } - } - - bool - ProcessUsingSpringBoard() const - { - return m_flags.Test (eFlagsUsingSBS); - } - - lldb_private::ArchSpec& - GetArchSpec() - { - return m_arch_spec; - } - const lldb_private::ArchSpec& - GetArchSpec() const - { - return m_arch_spec; - } - - CreateArchCalback - GetArchCreateCallback(); - - enum - { - eFlagsNone = 0, - eFlagsAttached = (1 << 0), - eFlagsUsingSBS = (1 << 1) - }; - - void - Clear ( ); - - lldb_private::Error - ReplyToAllExceptions(); - - lldb_private::Error - PrivateResume ( lldb::tid_t tid); - - lldb_private::Flags & - GetFlags () - { - return m_flags; - } - - const lldb_private::Flags & - GetFlags () const - { - return m_flags; - } - - bool - STDIOIsOurs() const - { - return m_stdio_ours; - } - - void - SetSTDIOIsOurs(bool b) - { - m_stdio_ours = b; - } - - uint32_t - UpdateThreadListIfNeeded (); - -private: - - void - DidLaunchOrAttach (); - - lldb_private::Error - DoSIGSTOP (bool clear_all_breakpoints); - - lldb_private::Error - WillLaunchOrAttach (); - -// static void * -// WaitForChildProcessToExit (void *pid_ptr); -// -// - //------------------------------------------------------------------ - // For ProcessMacOSX only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (ProcessMacOSX); - -}; - -#endif // liblldb_MacOSXProcess_H_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXLog.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXLog.cpp deleted file mode 100644 index b4dfda3854b..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXLog.cpp +++ /dev/null @@ -1,175 +0,0 @@ -//===-- ProcessMacOSXLog.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ProcessMacOSXLog.h" - -#include "lldb/Interpreter/Args.h" -#include "lldb/Core/StreamFile.h" - -#include "ProcessMacOSX.h" - -using namespace lldb; -using namespace lldb_private; - -// We want to avoid global constructors where code needs to be run so here we -// control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_lob_sp the first time this function is -// called. -static LogSP & -GetLog () -{ - static LogSP g_log_sp; - return g_log_sp; -} - -LogSP -ProcessMacOSXLog::GetLogIfAllCategoriesSet (uint32_t mask) -{ - LogSP log(GetLog ()); - if (log && mask) - { - uint32_t log_mask = log->GetMask().Get(); - if ((log_mask & mask) != mask) - return LogSP(); - } - return log; -} - - -void -ProcessMacOSXLog::DisableLog (Args &args, Stream *feedback_strm) -{ - LogSP log (GetLog ()); - if (log) - { - uint32_t flag_bits = 0; - const size_t argc = args.GetArgumentCount (); - if (argc > 0) - { - flag_bits = log->GetMask().Get(); - for (size_t i = 0; i < argc; ++i) - { - const char *arg = args.GetArgumentAtIndex (i); - - if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~PD_LOG_ALL; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~PD_LOG_BREAKPOINTS; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~PD_LOG_DEFAULT; - else if (::strncasecmp (arg, "exc", 3) == 0 ) flag_bits &= ~PD_LOG_EXCEPTIONS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~PD_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~PD_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~PD_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "protections")== 0 ) flag_bits &= ~PD_LOG_PROCESS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~PD_LOG_STEP; - else if (::strcasecmp (arg, "task") == 0 ) flag_bits &= ~PD_LOG_TASK; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~PD_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~PD_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~PD_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories (feedback_strm); - } - } - } - if (flag_bits == 0) - GetLog().reset(); - else - log->GetMask().Reset (flag_bits); - } -} - -LogSP -ProcessMacOSXLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm) -{ - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the same. - uint32_t flag_bits = 0; - LogSP log(GetLog ()); - if (log) - flag_bits = log->GetMask().Get(); - - // Now make a new log with this stream if one was provided - if (log_stream_sp) - { - log = make_shared<Log>(log_stream_sp); - GetLog () = log; - } - - if (log) - { - bool got_unknown_category = false; - const size_t argc = args.GetArgumentCount(); - for (size_t i=0; i<argc; ++i) - { - const char *arg = args.GetArgumentAtIndex(i); - - if (::strcasecmp (arg, "all") == 0 ) flag_bits |= PD_LOG_ALL; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= PD_LOG_BREAKPOINTS; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= PD_LOG_DEFAULT; - else if (::strncasecmp (arg, "exc", 3) == 0 ) flag_bits |= PD_LOG_EXCEPTIONS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= PD_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= PD_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= PD_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "protections")== 0 ) flag_bits |= PD_LOG_MEMORY_PROTECTIONS; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= PD_LOG_PROCESS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= PD_LOG_STEP; - else if (::strcasecmp (arg, "task") == 0 ) flag_bits |= PD_LOG_TASK; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= PD_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= PD_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= PD_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) - { - got_unknown_category = true; - ListLogCategories (feedback_strm); - } - } - } - if (flag_bits == 0) - flag_bits = PD_LOG_DEFAULT; - log->GetMask().Reset(flag_bits); - log->GetOptions().Reset(log_options); - } - return log; -} - -void -ProcessMacOSXLog::ListLogCategories (Stream *strm) -{ - strm->Printf("Logging categories for '%s':\n" - "\tall - turn on all available logging categories\n" - "\tbreak - log breakpoints\n" - "\tdefault - enable the default set of logging categories for liblldb\n" - "\tmemory - log memory reads and writes\n" - "\tdata-short - log memory bytes for memory reads and writes for short transactions only\n" - "\tdata-long - log memory bytes for memory reads and writes for all transactions\n" - "\tprocess - log process events and activities\n" - "\tprotections - log memory protections\n" - "\ttask - log mach task calls\n" - "\tthread - log thread events and activities\n" - "\tstep - log step related activities\n" - "\tverbose - enable verbose logging\n" - "\twatch - log watchpoint related activities\n", ProcessMacOSX::GetPluginNameStatic()); -} - - -void -ProcessMacOSXLog::LogIf (uint32_t mask, const char *format, ...) -{ - LogSP log(ProcessMacOSXLog::GetLogIfAllCategoriesSet (mask)); - if (log) - { - va_list args; - va_start (args, format); - log->VAPrintf (format, args); - va_end (args); - } -} diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXLog.h b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXLog.h deleted file mode 100644 index 5645a7f6cda..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXLog.h +++ /dev/null @@ -1,65 +0,0 @@ -//===-- ProcessMacOSXLog.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_ProcessMacOSXLog_h_ -#define liblldb_ProcessMacOSXLog_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes - -// Project includes -#include "lldb/Core/Log.h" - -#define PD_LOG_VERBOSE (1u << 0) -#define PD_LOG_PROCESS (1u << 1) -#define PD_LOG_THREAD (1u << 2) -#define PD_LOG_EXCEPTIONS (1u << 3) -#define PD_LOG_MEMORY (1u << 4) // Log memory reads/writes calls -#define PD_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes -#define PD_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes -#define PD_LOG_MEMORY_PROTECTIONS (1u << 7) // Log memory protection changes -#define PD_LOG_BREAKPOINTS (1u << 8) -#define PD_LOG_WATCHPOINTS (1u << 9) -#define PD_LOG_STEP (1u << 10) -#define PD_LOG_TASK (1u << 11) -#define PD_LOG_ALL (UINT32_MAX) -#define PD_LOG_DEFAULT (PD_LOG_PROCESS |\ - PD_LOG_TASK |\ - PD_LOG_THREAD |\ - PD_LOG_EXCEPTIONS |\ - PD_LOG_MEMORY |\ - PD_LOG_MEMORY_DATA_SHORT |\ - PD_LOG_BREAKPOINTS |\ - PD_LOG_WATCHPOINTS |\ - PD_LOG_STEP ) - -class ProcessMacOSXLog -{ -public: - static lldb::LogSP - GetLogIfAllCategoriesSet(uint32_t mask = 0); - - static void - DisableLog (lldb_private::Args &args, lldb_private::Stream *feedback_strm); - - static void - DeleteLog (); - - static lldb::LogSP - EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, lldb_private::Args &args, lldb_private::Stream *feedback_strm); - - static void - ListLogCategories (lldb_private::Stream *strm); - - static void - LogIf (uint32_t mask, const char *format, ...); -}; - -#endif // liblldb_ProcessMacOSXLog_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXRemote.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXRemote.cpp deleted file mode 100644 index a9315b71fab..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXRemote.cpp +++ /dev/null @@ -1,1819 +0,0 @@ -//===-- ProcessMacOSXRemote.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -//---------------------------------------------------------------------- -// -// ProcessMacOSXRemote.cpp -// liblldb -// -// Created by Greg Clayton on 4/21/09. -// -// -//---------------------------------------------------------------------- - -// C Includes -#include <errno.h> - -// C++ Includes -//#include <algorithm> -//#include <map> - -// Other libraries and framework includes - -// Project includes -#include "ProcessMacOSXRemote.h" -#include "ProcessMacOSXLog.h" -#include "ThreadMacOSX.h" - -Process* -ProcessMacOSXRemote::CreateInstance (Target &target) -{ - return new ProcessMacOSXRemote (target); -} - -bool -ProcessMacOSXRemote::CanDebug(Target &target) -{ - // For now we are just making sure the file exists for a given module - ModuleSP exe_module_sp(target.GetExecutableModule()); - if (exe_module_sp.get()) - return exe_module_sp->GetFileSpec().Exists(); - return false; -} - -//---------------------------------------------------------------------- -// ProcessMacOSXRemote constructor -//---------------------------------------------------------------------- -ProcessMacOSXRemote::ProcessMacOSXRemote(Target& target) : - Process (target), - m_flags (0), - m_arch_spec (), - m_dynamic_loader_ap (), - m_byte_order(eByteOrderInvalid) -{ -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -ProcessMacOSXRemote::~DCProcessMacOSXRemote() -{ - Clear(); -} - -//---------------------------------------------------------------------- -// Process Control -//---------------------------------------------------------------------- -lldb::pid_t -ProcessMacOSXRemote::DoLaunch -( - Module* module, - char const *argv[], - char const *envp[], - const char *stdin_path, - const char *stdout_path, - const char *stderr_path -) -{ -// ::LogSetBitMask (PD_LOG_DEFAULT); -// ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD); -// ::LogSetLogFile ("/dev/stdout"); - - ObjectFile * object_file = module->GetObjectFile(); - if (object_file) - { - char exec_file_path[PATH_MAX]; - FileSpec* file_spec_ptr = object_file->GetFileSpec(); - if (file_spec_ptr) - file_spec_ptr->GetPath(exec_file_path, sizeof(exec_file_path)); - - ArchSpec arch_spec(module->GetArchitecture()); - - switch (arch_spec.GetCPUType()) - { - - } - // Set our user ID to our process ID. - SetID(LaunchForDebug(exec_file_path, argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, eLaunchDefault, GetError())); - } - else - { - // Set our user ID to an invalid process ID. - SetID(LLDB_INVALID_PROCESS_ID); - GetError().SetErrorToGenericError (); - GetError().SetErrorStringWithFormat ("Failed to get object file from '%s' for arch %s.\n", module->GetFileSpec().GetFilename().AsCString(), module->GetArchitecture().AsCString()); - } - - // Return the process ID we have - return GetID(); -} - -lldb::pid_t -ProcessMacOSXRemote::DoAttach (lldb::pid_t attach_pid) -{ - // Set our user ID to the attached process ID (which can be invalid if - // the attach fails - lldb::pid_t pid = AttachForDebug(attach_pid); - SetID(pid); - -// if (pid != LLDB_INVALID_PROCESS_ID) -// { -// // Wait for a process stopped event, but don't consume it -// if (WaitForEvents(LLDB_EVENT_STOPPED, NULL, 30)) -// { -// } -// } -// - // Return the process ID we have - return pid; -} - - -void -ProcessMacOSXRemote::DidLaunch () -{ - if (GetID() == LLDB_INVALID_PROCESS_ID) - { - m_dynamic_loader_ap.reset(); - } - else - { - Module * exe_module = GetTarget().GetExecutableModule ().get(); - assert(exe_module); - ObjectFile *exe_objfile = exe_module->GetObjectFile(); - assert(exe_objfile); - m_byte_order = exe_objfile->GetByteOrder(); - assert(m_byte_order != eByteOrderInvalid); - // Install a signal handler so we can catch when our child process - // dies and set the exit status correctly. - m_wait_thread = Host::ThreadCreate (ProcessMacOSXRemote::WaitForChildProcessToExit, &m_uid, &m_error); - if (m_wait_thread != LLDB_INVALID_HOST_THREAD) - { - // Don't need to get the return value of this thread, so just let - // it clean up after itself when it dies. - Host::ThreadDetach (m_wait_thread, NULL); - } - m_dynamic_loader_ap.reset(DynamicLoader::FindPlugin(this, "macosx-dyld")); - } - -} - -void -ProcessMacOSXRemote::DidAttach () -{ - DidLaunch (); - m_need_to_run_did_attach = true; -} - -bool -ProcessMacOSXRemote::DoResume () -{ - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSXRemote::Resume()"); - State state = GetState(); - - if (CanResume(state)) - { - PrivateResume(LLDB_INVALID_THREAD_ID); - } - else if (state == eStateRunning) - { - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "Resume() - task 0x%x is running, ignoring...", m_task.TaskPort()); - GetError().Clear(); - - } - else - { - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "Resume() - task 0x%x can't continue, ignoring...", m_task.TaskPort()); - GetError().SetError(UINT_MAX, Error::Generic); - } - - return GetError().Success(); -} - -size_t -ProcessMacOSXRemote::GetSoftwareBreakpointTrapOpcode (BreakpointSite *bp_site) -{ - ModuleSP exe_module_sp(GetTarget().GetExecutableModule()); - if (exe_module_sp.get()) - { - const ArchSpec &exe_arch = exe_module_sp->GetArchitecture(); - const uint8_t *trap_opcode = NULL; - uint32_t trap_opcode_size = 0; - - static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; - //static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE }; - static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 }; - static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; - - switch (exe_arch.GetCPUType()) - { - case CPU_TYPE_ARM: - // TODO: fill this in for ARM. We need to dig up the symbol for - // the address in the breakpoint location and figure out if it is - // an ARM or Thumb breakpoint. - trap_opcode = g_arm_breakpoint_opcode; - trap_opcode_size = sizeof(g_arm_breakpoint_opcode); - break; - - case CPU_TYPE_POWERPC: - case CPU_TYPE_POWERPC64: - trap_opcode = g_ppc_breakpoint_opcode; - trap_opcode_size = sizeof(g_ppc_breakpoint_opcode); - break; - - case CPU_TYPE_I386: - case CPU_TYPE_X86_64: - trap_opcode = g_i386_breakpoint_opcode; - trap_opcode_size = sizeof(g_i386_breakpoint_opcode); - break; - - default: - assert(!"Unhandled architecture in ProcessMacOSXRemote::GetSoftwareBreakpointTrapOpcode()"); - return 0; - } - - if (trap_opcode && trap_opcode_size) - { - if (bp_loc->SetTrapOpcode(trap_opcode, trap_opcode_size)) - return trap_opcode_size; - } - } - // No executable yet, so we can't tell what the breakpoint opcode will be. - return 0; -} -uint32_t -ProcessMacOSXRemote::UpdateThreadListIfNeeded () -{ - // locker will keep a mutex locked until it goes out of scope - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_THREAD); - if (log && log->GetMask().IsSet(PD_LOG_VERBOSE)) - log->Printf ("ProcessMacOSXRemote::%s (pid = %4.4x)", __FUNCTION__, GetID()); - - const uint32_t stop_id = GetStopID(); - if (m_thread_list.GetSize() == 0 || stop_id != m_thread_list.GetID()) - { - m_thread_list.SetID (stop_id); - thread_array_t thread_list = NULL; - mach_msg_type_number_t thread_list_count = 0; - task_t task = Task().TaskPort(); - Error err(::task_threads (task, &thread_list, &thread_list_count), Error::MachKernel); - - if (log || err.Fail()) - err.Log(log, "::task_threads ( task = 0x%4.4x, thread_list => %p, thread_list_count => %u )", task, thread_list, thread_list_count); - - if (err.GetError() == KERN_SUCCESS && thread_list_count > 0) - { - ThreadList curr_thread_list; - - size_t idx; - // Iterator through the current thread list and see which threads - // we already have in our list (keep them), which ones we don't - // (add them), and which ones are not around anymore (remove them). - for (idx = 0; idx < thread_list_count; ++idx) - { - const lldb::tid_t tid = thread_list[idx]; - ThreadSP thread_sp(m_thread_list.FindThreadByID (tid)); - if (thread_sp.get() == NULL) - thread_sp.reset (new ThreadMacOSX (this, tid)); - curr_thread_list.AddThread(thread_sp); - } - - m_thread_list = curr_thread_list; - - // Free the vm memory given to us by ::task_threads() - vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (lldb::tid_t)); - ::vm_deallocate (::mach_task_self(), - (vm_address_t)thread_list, - thread_list_size); - } - } - return m_thread_list.GetSize(); -} - -bool -ProcessMacOSXRemote::ShouldStop () -{ - // If we are attaching, let our dynamic loader plug-in know so it can get - // an initial list of shared libraries. - if (m_need_to_run_did_attach && m_dynamic_loader_ap.get()) - { - m_need_to_run_did_attach = false; - m_dynamic_loader_ap->DidAttach(); - } - - // We must be attaching if we don't already have a valid architecture - if (!m_arch_spec.IsValid()) - { - Module *exe_module = GetTarget().GetExecutableModule().get(); - if (exe_module) - m_arch_spec = exe_module->GetArchitecture(); - } - // Let all threads recover from stopping and do any clean up based - // on the previous thread state (if any). - UpdateThreadListIfNeeded (); - - if (m_thread_list.ShouldStop()) - { - // Let each thread know of any exceptions - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS); - task_t task = m_task.TaskPort(); - size_t i; - for (i=0; i<m_exception_messages.size(); ++i) - { - // Let the thread list figure use the ProcessMacOSXRemote to forward all exceptions - // on down to each thread. - if (m_exception_messages[i].state.task_port == task) - { - ThreadSP thread_sp(m_thread_list.FindThreadByID(m_exception_messages[i].state.thread_port)); - if (thread_sp.get()) - { - ThreadMacOSX *macosx_thread = (ThreadMacOSX *)thread_sp.get(); - macosx_thread->NotifyException (m_exception_messages[i].state); - } - } - if (log) - m_exception_messages[i].Log(log); - } - return true; - } - return false; -} - -bool -ProcessMacOSXRemote::DoHalt () -{ - return Kill (SIGINT); -} - -bool -ProcessMacOSXRemote::WillDetach () -{ - State state = GetState(); - - if (IsRunning(state)) - { - m_error.SetErrorToGenericError(); - m_error.SetErrorString("Process must be stopped in order to detach."); - return false; - } - return true; -} - -bool -ProcessMacOSXRemote::DoDetach () -{ - m_use_public_queue = false; - bool success = Detach(); - m_use_public_queue = true; - if (success) - SetState (eStateDetached); - return success; -} - -bool -ProcessMacOSXRemote::DoKill (int signal) -{ - return Kill (signal); -} - - -//------------------------------------------------------------------ -// Thread Queries -//------------------------------------------------------------------ - -Thread * -ProcessMacOSXRemote::GetCurrentThread () -{ - return m_thread_list.GetCurrentThread().get(); -} - -ByteOrder -ProcessMacOSXRemote::GetByteOrder () const -{ - return m_byte_order; -} - - - -//------------------------------------------------------------------ -// Process Queries -//------------------------------------------------------------------ - -bool -ProcessMacOSXRemote::IsAlive () -{ - return MachTask::IsValid (Task().TaskPort()); -} - -bool -ProcessMacOSXRemote::IsRunning () -{ - return LLDB_STATE_IS_RUNNING(GetState()); -} - -lldb::addr_t -ProcessMacOSXRemote::GetImageInfoAddress() -{ - return Task().GetDYLDAllImageInfosAddress(); -} - -DynamicLoader * -ProcessMacOSXRemote::GetDynamicLoader() -{ - return m_dynamic_loader_ap.get(); -} - -//------------------------------------------------------------------ -// Process Memory -//------------------------------------------------------------------ - -size_t -ProcessMacOSXRemote::DoReadMemory (lldb::addr_t addr, void *buf, size_t size) -{ - return Task().ReadMemory(addr, buf, size); -} - -size_t -ProcessMacOSXRemote::DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size) -{ - return Task().WriteMemory(addr, buf, size); -} - -//------------------------------------------------------------------ -// Process STDIO -//------------------------------------------------------------------ - -size_t -ProcessMacOSXRemote::GetSTDOUT (char *buf, size_t buf_size) -{ - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSXRemote::%s (&%p[%u]) ...", __FUNCTION__, buf, buf_size); - Mutex::Locker locker(m_stdio_mutex); - size_t bytes_available = m_stdout_data.size(); - if (bytes_available > 0) - { - if (bytes_available > buf_size) - { - memcpy(buf, m_stdout_data.data(), buf_size); - m_stdout_data.erase(0, buf_size); - bytes_available = buf_size; - } - else - { - memcpy(buf, m_stdout_data.data(), bytes_available); - m_stdout_data.clear(); - } - } - return bytes_available; -} - -size_t -ProcessMacOSXRemote::GetSTDERR (char *buf, size_t buf_size) -{ - return 0; -} - -bool -ProcessMacOSXRemote::EnableBreakpoint (BreakpointLocation *bp) -{ - assert (bp != NULL); - - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_BREAKPOINTS); - lldb::user_id_t breakID = bp->GetID(); - lldb::addr_t addr = bp->GetAddress(); - if (bp->IsEnabled()) - { - if (log) - log->Printf("ProcessMacOSXRemote::EnableBreakpoint ( breakID = %d ) breakpoint already enabled.", breakID); - return true; - } - else - { - if (bp->HardwarePreferred()) - { - ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(bp->GetThreadID()).get(); - if (thread) - { - bp->SetHardwareIndex (thread->EnableHardwareBreakpoint(bp)); - if (bp->IsHardware()) - { - bp->SetEnabled(true); - return true; - } - } - } - - const size_t break_op_size = GetSoftwareBreakpointTrapOpcode (bp); - assert (break_op_size > 0); - const uint8_t * const break_op = bp->GetTrapOpcodeBytes(); - - if (break_op_size > 0) - { - // Save the original opcode by reading it - if (m_task.ReadMemory(addr, bp->GetSavedOpcodeBytes(), break_op_size) == break_op_size) - { - // Write a software breakpoint in place of the original opcode - if (m_task.WriteMemory(addr, break_op, break_op_size) == break_op_size) - { - uint8_t verify_break_op[4]; - if (m_task.ReadMemory(addr, verify_break_op, break_op_size) == break_op_size) - { - if (memcmp(break_op, verify_break_op, break_op_size) == 0) - { - bp->SetEnabled(true); - if (log) - log->Printf("ProcessMacOSXRemote::EnableBreakpoint ( breakID = %d ) SUCCESS.", breakID, (uint64_t)addr); - return true; - } - else - { - GetError().SetErrorString("Failed to verify the breakpoint trap in memory."); - } - } - else - { - GetError().SetErrorString("Unable to read memory to verify breakpoint trap."); - } - } - else - { - GetError().SetErrorString("Unable to write breakpoint trap to memory."); - } - } - else - { - GetError().SetErrorString("Unable to read memory at breakpoint address."); - } - } - } - - if (log) - { - const char *err_string = GetError().AsCString(); - log->Printf ("ProcessMacOSXRemote::EnableBreakpoint ( breakID = %d ) error: %s", - breakID, err_string ? err_string : "NULL"); - } - GetError().SetErrorToGenericError(); - return false; -} - -bool -ProcessMacOSXRemote::DisableBreakpoint (BreakpointLocation *bp) -{ - assert (bp != NULL); - lldb::addr_t addr = bp->GetAddress(); - lldb::user_id_t breakID = bp->GetID(); - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_BREAKPOINTS); - if (log) - log->Printf ("ProcessMacOSXRemote::DisableBreakpoint (breakID = %d) addr = 0x%8.8llx", breakID, (uint64_t)addr); - - if (bp->IsHardware()) - { - ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(bp->GetThreadID()).get(); - if (thread) - { - if (thread->DisableHardwareBreakpoint(bp)) - { - bp->SetEnabled(false); - if (log) - log->Printf ("ProcessMacOSXRemote::DisableBreakpoint (breakID = %d) (hardware) => success", breakID); - return true; - } - } - return false; - } - - const size_t break_op_size = bp->GetByteSize(); - assert (break_op_size > 0); - const uint8_t * const break_op = bp->GetTrapOpcodeBytes(); - if (break_op_size > 0) - { - // Clear a software breakpoint instruction - uint8_t curr_break_op[break_op_size]; - bool break_op_found = false; - - // Read the breakpoint opcode - if (m_task.ReadMemory(addr, curr_break_op, break_op_size) == break_op_size) - { - bool verify = false; - if (bp->IsEnabled()) - { - // Make sure we have the a breakpoint opcode exists at this address - if (memcmp(curr_break_op, break_op, break_op_size) == 0) - { - break_op_found = true; - // We found a valid breakpoint opcode at this address, now restore - // the saved opcode. - if (m_task.WriteMemory(addr, bp->GetSavedOpcodeBytes(), break_op_size) == break_op_size) - { - verify = true; - } - else - { - GetError().SetErrorString("Memory write failed when restoring original opcode."); - } - } - else - { - GetError().SetErrorString("Original breakpoint trap is no longer in memory."); - // Set verify to true and so we can check if the original opcode has already been restored - verify = true; - } - } - else - { - if (log) - log->Printf ("ProcessMacOSXRemote::DisableBreakpoint (breakID = %d) is already disabled", breakID); - // Set verify to true and so we can check if the original opcode is there - verify = true; - } - - if (verify) - { - uint8_t verify_opcode[break_op_size]; - // Verify that our original opcode made it back to the inferior - if (m_task.ReadMemory(addr, verify_opcode, break_op_size) == break_op_size) - { - // compare the memory we just read with the original opcode - if (memcmp(bp->GetSavedOpcodeBytes(), verify_opcode, break_op_size) == 0) - { - // SUCCESS - bp->SetEnabled(false); - if (log) - log->Printf ("ProcessMacOSXRemote::DisableBreakpoint (breakID = %d) SUCCESS", breakID); - return true; - } - else - { - if (break_op_found) - GetError().SetErrorString("Failed to restore original opcode."); - } - } - else - { - GetError().SetErrorString("Failed to read memory to verify that breakpoint trap was restored."); - } - } - } - else - { - GetError().SetErrorString("Unable to read memory that should contain the breakpoint trap."); - } - } - - GetError().SetErrorToGenericError(); - return false; -} - -bool -ProcessMacOSXRemote::EnableWatchpoint (WatchpointLocation *wp) -{ - if (wp) - { - lldb::user_id_t watchID = wp->GetID(); - lldb::addr_t addr = wp->GetAddress(); - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_WATCHPOINTS); - if (log) - log->Printf ("ProcessMacOSXRemote::EnableWatchpoint(watchID = %d)", watchID); - if (wp->IsEnabled()) - { - if (log) - log->Printf("ProcessMacOSXRemote::EnableWatchpoint(watchID = %d) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr); - return true; - } - else - { - ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(wp->GetThreadID()).get(); - if (thread) - { - wp->SetHardwareIndex (thread->EnableHardwareWatchpoint (wp)); - if (wp->IsHardware ()) - { - wp->SetEnabled(true); - return true; - } - } - else - { - GetError().SetErrorString("Watchpoints currently only support thread specific watchpoints."); - } - } - } - return false; -} - -bool -ProcessMacOSXRemote::DisableWatchpoint (WatchpointLocation *wp) -{ - if (wp) - { - lldb::user_id_t watchID = wp->GetID(); - - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_WATCHPOINTS); - - lldb::addr_t addr = wp->GetAddress(); - if (log) - log->Printf ("ProcessMacOSXRemote::DisableWatchpoint (watchID = %d) addr = 0x%8.8llx", watchID, (uint64_t)addr); - - if (wp->IsHardware()) - { - ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(wp->GetThreadID()).get(); - if (thread) - { - if (thread->DisableHardwareWatchpoint (wp)) - { - wp->SetEnabled(false); - if (log) - log->Printf ("ProcessMacOSXRemote::DisableWatchpoint (watchID = %d) addr = 0x%8.8llx (hardware) => success", watchID, (uint64_t)addr); - return true; - } - } - } - // TODO: clear software watchpoints if we implement them - } - else - { - GetError().SetErrorString("Watchpoint location argument was NULL."); - } - GetError().SetErrorToGenericError(); - return false; -} - - -static ProcessMacOSXRemote::CreateArchCalback -ArchDCScriptInterpreter::TypeMap(const ArchSpec& arch_spec, ProcessMacOSXRemote::CreateArchCalback callback, bool add ) -{ - // We must wrap the "g_arch_map" file static in a function to avoid - // any global constructors so we don't get a build verification error - typedef std::multimap<ArchSpec, ProcessMacOSXRemote::CreateArchCalback> ArchToProtocolMap; - static ArchToProtocolMap g_arch_map; - - if (add) - { - g_arch_map.insert(std::make_pair(arch_spec, callback)); - return callback; - } - else - { - ArchToProtocolMap::const_iterator pos = g_arch_map.find(arch_spec); - if (pos != g_arch_map.end()) - { - return pos->second; - } - } - return NULL; -} - -void -ProcessMacOSXRemote::AddArchCreateDCScriptInterpreter::Type(const ArchSpec& arch_spec, CreateArchCalback callback) -{ - ArchDCScriptInterpreter::TypeMap (arch_spec, callback, true); -} - -ProcessMacOSXRemote::CreateArchCalback -ProcessMacOSXRemote::GetArchCreateDCScriptInterpreter::Type() -{ - return ArchDCScriptInterpreter::TypeMap (m_arch_spec, NULL, false); -} - -void -ProcessMacOSXRemote::Clear() -{ - // Clear any cached thread list while the pid and task are still valid - - m_task.Clear(); - // Now clear out all member variables - CloseChildFileDescriptors(); - - m_flags = eFlagsNone; - m_thread_list.Clear(); - { - Mutex::Locker locker(m_exception_messages_mutex); - m_exception_messages.clear(); - } - -} - - -bool -ProcessMacOSXRemote::Kill (int signal) -{ - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS); - if (log) - log->Printf ("ProcessMacOSXRemote::Kill(signal = %d)", signal); - State state = GetState(); - - if (IsRunning(state)) - { - if (::kill (GetID(), signal) == 0) - { - GetError().Clear(); - } - else - { - GetError().SetErrorToErrno(); - GetError().LogIfError(log, "ProcessMacOSXRemote::Kill(%d)", signal); - } - } - else - { - if (log) - log->Printf ("ProcessMacOSXRemote::Kill(signal = %d) pid %u (task = 0x%4.4x) was't running, ignoring...", signal, GetID(), m_task.TaskPort()); - GetError().Clear(); - } - return GetError().Success(); - -} - - -bool -ProcessMacOSXRemote::Detach() -{ - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSXRemote::Detach()"); - - State state = GetState(); - - if (!IsRunning(state)) - { - // Resume our process - PrivateResume(LLDB_INVALID_THREAD_ID); - - // We have resumed and now we wait for that event to get posted - Event event; - if (WaitForPrivateEvents(LLDB_EVENT_RUNNING, &event, 2) == false) - return false; - - - // We need to be stopped in order to be able to detach, so we need - // to send ourselves a SIGSTOP - if (Kill(SIGSTOP)) - { - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_PROCESS); - - lldb::pid_t pid = GetID(); - // Wait for our process stop event to get posted - if (WaitForPrivateEvents(LLDB_EVENT_STOPPED, &event, 2) == false) - { - GetError().Log(log, "::kill (pid = %u, SIGSTOP)", pid); - return false; - } - - // Shut down the exception thread and cleanup our exception remappings - m_task.ShutDownExceptionThread(); - - // Detach from our process while we are stopped. - errno = 0; - - // Detach from our process - ::ptrace (PT_DETACH, pid, (caddr_t)1, 0); - - GetError().SetErrorToErrno(); - - if (log || GetError().Fail()) - GetError().Log(log, "::ptrace (PT_DETACH, %u, (caddr_t)1, 0)", pid); - - // Resume our task - m_task.Resume(); - - // NULL our task out as we have already retored all exception ports - m_task.Clear(); - - // Clear out any notion of the process we once were - Clear(); - } - } - else - { - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSXRemote::Detach() error: process must be stopped (SIGINT the process first)."); - } - return false; -} - - - -void -ProcessMacOSXRemote::ReplyToAllExceptions() -{ - Mutex::Locker locker(m_exception_messages_mutex); - if (m_exception_messages.empty() == false) - { - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_EXCEPTIONS); - - MachException::Message::iterator pos; - MachException::Message::iterator begin = m_exception_messages.begin(); - MachException::Message::iterator end = m_exception_messages.end(); - for (pos = begin; pos != end; ++pos) - { - if (log) - log->Printf ("Replying to exception %d...", std::distance(begin, pos)); - int resume_signal = 0; - ThreadSP thread_sp = m_thread_list.FindThreadByID(pos->state.thread_port); - if (thread_sp.get()) - resume_signal = thread_sp->GetResumeSignal(); - GetError() = pos->Reply (Task().TaskPort(), GetID(), resume_signal); - GetError().LogIfError(log, "Error replying to exception"); - } - - // Erase all exception message as we should have used and replied - // to them all already. - m_exception_messages.clear(); - } -} -void -ProcessMacOSXRemote::PrivateResume (lldb::tid_t tid) -{ - Mutex::Locker locker(m_exception_messages_mutex); - ReplyToAllExceptions(); - - // Let the thread prepare to resume and see if any threads want us to - // step over a breakpoint instruction (ProcessWillResume will modify - // the value of stepOverBreakInstruction). - //StateType process_state = m_thread_list.ProcessWillResume(this); - - // Set our state accordingly - SetState(eStateRunning); - - // Now resume our task. - GetError() = m_task.Resume(); - -} - -// Called by the exception thread when an exception has been received from -// our process. The exception message is completely filled and the exception -// data has already been copied. -void -ProcessMacOSXRemote::ExceptionMessageReceived (const MachException::Message& exceptionMessage) -{ - Mutex::Locker locker(m_exception_messages_mutex); - - if (m_exception_messages.empty()) - m_task.Suspend(); - - ProcessMacOSXLog::LogIf (PD_LOG_EXCEPTIONS, "ProcessMacOSXRemote::ExceptionMessageReceived ( )"); - - // Use a locker to automatically unlock our mutex in case of exceptions - // Add the exception to our internal exception stack - m_exception_messages.push_back(exceptionMessage); -} - - -//bool -//ProcessMacOSXRemote::GetProcessInfo (struct kinfo_proc* proc_info) -//{ -// int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, GetID() }; -// size_t buf_size = sizeof(struct kinfo_proc); -// -// if (::sysctl (mib, (unsigned)(sizeof(mib)/sizeof(int)), &proc_info, &buf_size, NULL, 0) == 0) -// return buf_size > 0; -// -// return false; -//} -// -// -void -ProcessMacOSXRemote::ExceptionMessageBundleComplete() -{ - // We have a complete bundle of exceptions for our child process. - Mutex::Locker locker(m_exception_messages_mutex); - ProcessMacOSXLog::LogIf (PD_LOG_EXCEPTIONS, "%s: %d exception messages.", __PRETTY_FUNCTION__, m_exception_messages.size()); - if (!m_exception_messages.empty()) - { - SetState (eStateStopped); - } - else - { - ProcessMacOSXLog::LogIf (PD_LOG_EXCEPTIONS, "%s empty exception messages bundle.", __PRETTY_FUNCTION__, m_exception_messages.size()); - } -} - -bool -ProcessMacOSXRemote::ReleaseChildFileDescriptors ( int *stdin_fileno, int *stdout_fileno, int *stderr_fileno ) -{ - if (stdin_fileno) - *stdin_fileno = m_child_stdin; - if (stdout_fileno) - *stdout_fileno = m_child_stdout; - if (stderr_fileno) - *stderr_fileno = m_child_stderr; - // Stop the stdio thread if we have one, but don't have it close the child - // file descriptors since we are giving control of these descriptors to the - // caller - bool close_child_fds = false; - StopSTDIOThread(close_child_fds); - return true; -} - -void -ProcessMacOSXRemote::AppendSTDOUT (char* s, size_t len) -{ - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "ProcessMacOSXRemote::%s (<%d> %s) ...", __FUNCTION__, len, s); - Mutex::Locker locker(m_stdio_mutex); - m_stdout_data.append(s, len); - AppendEvent (LLDB_EVENT_STDIO); -} - -void * -ProcessMacOSXRemote::STDIOThread(void *arg) -{ - ProcessMacOSXRemote *proc = (ProcessMacOSXRemote*) arg; - - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS); - if (log) - log->Printf ("ProcessMacOSXRemote::%s (arg = %p) thread starting...", __FUNCTION__, arg); - - // We start use a base and more options so we can control if we - // are currently using a timeout on the mach_msg. We do this to get a - // bunch of related exceptions on our exception port so we can process - // then together. When we have multiple threads, we can get an exception - // per thread and they will come in consecutively. The main thread loop - // will start by calling mach_msg to without having the MACH_RCV_TIMEOUT - // flag set in the options, so we will wait forever for an exception on - // our exception port. After we get one exception, we then will use the - // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current - // exceptions for our process. After we have received the last pending - // exception, we will get a timeout which enables us to then notify - // our main thread that we have an exception bundle available. We then wait - // for the main thread to tell this exception thread to start trying to get - // exceptions messages again and we start again with a mach_msg read with - // infinite timeout. - Error err; - int stdout_fd = proc->GetStdoutFileDescriptor(); - int stderr_fd = proc->GetStderrFileDescriptor(); - if (stdout_fd == stderr_fd) - stderr_fd = -1; - - while (stdout_fd >= 0 || stderr_fd >= 0) - { - ::pthread_testcancel (); - - fd_set read_fds; - FD_ZERO (&read_fds); - if (stdout_fd >= 0) - FD_SET (stdout_fd, &read_fds); - if (stderr_fd >= 0) - FD_SET (stderr_fd, &read_fds); - int nfds = std::max<int>(stdout_fd, stderr_fd) + 1; - - int num_set_fds = select (nfds, &read_fds, NULL, NULL, NULL); - if (log) - log->Printf("select (nfds, &read_fds, NULL, NULL, NULL) => %d", num_set_fds); - - if (num_set_fds < 0) - { - int select_errno = errno; - if (log) - { - err.SetError (select_errno, Error::POSIX); - err.LogIfError(log, "select (nfds, &read_fds, NULL, NULL, NULL) => %d", num_set_fds); - } - - switch (select_errno) - { - case EAGAIN: // The kernel was (perhaps temporarily) unable to allocate the requested number of file descriptors, or we have non-blocking IO - break; - case EBADF: // One of the descriptor sets specified an invalid descriptor. - return NULL; - break; - case EINTR: // A signal was delivered before the time limit expired and before any of the selected events occurred. - case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. - default: // Other unknown error - break; - } - } - else if (num_set_fds == 0) - { - } - else - { - char s[1024]; - s[sizeof(s)-1] = '\0'; // Ensure we have NULL termination - int bytes_read = 0; - if (stdout_fd >= 0 && FD_ISSET (stdout_fd, &read_fds)) - { - do - { - bytes_read = ::read (stdout_fd, s, sizeof(s)-1); - if (bytes_read < 0) - { - int read_errno = errno; - if (log) - log->Printf("read (stdout_fd, ) => %d errno: %d (%s)", bytes_read, read_errno, strerror(read_errno)); - } - else if (bytes_read == 0) - { - // EOF... - if (log) - log->Printf("read (stdout_fd, ) => %d (reached EOF for child STDOUT)", bytes_read); - stdout_fd = -1; - } - else if (bytes_read > 0) - { - proc->AppendSTDOUT(s, bytes_read); - } - - } while (bytes_read > 0); - } - - if (stderr_fd >= 0 && FD_ISSET (stderr_fd, &read_fds)) - { - do - { - bytes_read = ::read (stderr_fd, s, sizeof(s)-1); - if (bytes_read < 0) - { - int read_errno = errno; - if (log) - log->Printf("read (stderr_fd, ) => %d errno: %d (%s)", bytes_read, read_errno, strerror(read_errno)); - } - else if (bytes_read == 0) - { - // EOF... - if (log) - log->Printf("read (stderr_fd, ) => %d (reached EOF for child STDERR)", bytes_read); - stderr_fd = -1; - } - else if (bytes_read > 0) - { - proc->AppendSTDOUT(s, bytes_read); - } - - } while (bytes_read > 0); - } - } - } - - if (log) - log->Printf("ProcessMacOSXRemote::%s (%p): thread exiting...", __FUNCTION__, arg); - - return NULL; -} - -lldb::pid_t -ProcessMacOSXRemote::AttachForDebug (lldb::pid_t pid) -{ - // Clear out and clean up from any current state - Clear(); - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS); - if (pid != 0) - { - SetState(eStateAttaching); - SetID(pid); - // Let ourselves know we are going to be using SBS if the correct flag bit is set... -#if defined (__arm__) - if (IsSBProcess(pid)) - m_flags |= eFlagsUsingSBS; -#endif - m_task.StartExceptionThread(GetError()); - - if (GetError().Success()) - { - if (ptrace (PT_ATTACHEXC, pid, 0, 0) == 0) - { - m_flags.Set (eFlagsAttached); - // Sleep a bit to let the exception get received and set our process status - // to stopped. - ::usleep(250000); - if (log) - log->Printf ("successfully attached to pid %d", pid); - return GetID(); - } - else - { - GetError().SetErrorToErrno(); - if (log) - log->Printf ("error: failed to attach to pid %d", pid); - } - } - else - { - GetError().Log(log, "ProcessMacOSXRemote::%s (pid = %i) failed to start exception thread", __FUNCTION__, pid); - } - } - return LLDB_INVALID_PROCESS_ID; -} - -lldb::pid_t -ProcessMacOSXRemote::LaunchForDebug -( - const char *path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - PDLaunchType launch_type, - Error &launch_err) -{ - // Clear out and clean up from any current state - Clear(); - - m_arch_spec = arch_spec; - - if (launch_type == eLaunchDefault) - launch_type = eLaunchPosixSpawn; - - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS); - if (log) - log->Printf ("%s( path = '%s', argv = %p, envp = %p, launch_type = %u )", __FUNCTION__, path, argv, envp, launch_type); - - // Fork a child process for debugging - SetState(eStateLaunching); - switch (launch_type) - { - case eLaunchForkExec: - SetID(ProcessMacOSXRemote::ForkChildForPTraceDebugging(path, argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, this, launch_err)); - break; - - case eLaunchPosixSpawn: - SetID(ProcessMacOSXRemote::PosixSpawnChildForPTraceDebugging(path, argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, this, launch_err)); - break; - -#if defined (__arm__) - - case eLaunchSpringBoard: - { - const char *app_ext = strstr(path, ".app"); - if (app_ext != NULL) - { - std::string app_bundle_path(path, app_ext + strlen(".app")); - return SBLaunchForDebug (app_bundle_path.c_str(), argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, launch_err); - } - } - break; - -#endif - - default: - // Invalid launch - launch_err.SetErrorToGenericError (); - return LLDB_INVALID_PROCESS_ID; - } - - lldb::pid_t pid = GetID(); - - if (pid == LLDB_INVALID_PROCESS_ID) - { - // If we don't have a valid process ID and no one has set the error, - // then return a generic error - if (launch_err.Success()) - launch_err.SetErrorToGenericError (); - } - else - { - // Make sure we can get our task port before going any further - m_task.TaskPortForProcessID (launch_err); - - // If that goes well then kick off our exception thread - if (launch_err.Success()) - m_task.StartExceptionThread(launch_err); - - if (launch_err.Success()) - { - //m_path = path; -// size_t i; -// if (argv) -// { -// char const *arg; -// for (i=0; (arg = argv[i]) != NULL; i++) -// m_args.push_back(arg); -// } - - StartSTDIOThread(); - - if (launch_type == eLaunchPosixSpawn) - { - - //SetState (eStateAttaching); - errno = 0; - if (::ptrace (PT_ATTACHEXC, pid, 0, 0) == 0) - launch_err.Clear(); - else - launch_err.SetErrorToErrno(); - - if (launch_err.Fail() || log) - launch_err.Log(log, "::ptrace (PT_ATTACHEXC, pid = %i, 0, 0 )", pid); - - if (launch_err.Success()) - m_flags.Set (eFlagsAttached); - else - SetState (eStateExited); - } - else - { - launch_err.Clear(); - } - } - else - { - // We were able to launch the process, but not get its task port - // so now we need to make it sleep with da fishes. - SetID(LLDB_INVALID_PROCESS_ID); - ::kill (pid, SIGCONT); - ::kill (pid, SIGKILL); - pid = LLDB_INVALID_PROCESS_ID; - } - - } - return pid; -} - -lldb::pid_t -ProcessMacOSXRemote::PosixSpawnChildForPTraceDebugging -( - const char *path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - ProcessMacOSXRemote* process, - Error &err -) -{ - posix_spawnattr_t attr; - - Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS); - - Error local_err; // Errors that don't affect the spawning. - if (log) - log->Printf ("%s ( path='%s', argv=%p, envp=%p, process )", __FUNCTION__, path, argv, envp); - err.SetError( ::posix_spawnattr_init (&attr), Error::POSIX); - if (err.Fail() || log) - err.Log(log, "::posix_spawnattr_init ( &attr )"); - if (err.Fail()) - return LLDB_INVALID_PROCESS_ID; - - err.SetError( ::posix_spawnattr_setflags (&attr, POSIX_SPAWN_START_SUSPENDED), Error::POSIX); - if (err.Fail() || log) - err.Log(log, "::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED )"); - if (err.Fail()) - return LLDB_INVALID_PROCESS_ID; - -#if !defined(__arm__) - - // We don't need to do this for ARM, and we really shouldn't now that we - // have multiple CPU subtypes and no posix_spawnattr call that allows us - // to set which CPU subtype to launch... - cpu_type_t cpu = arch_spec.GetCPUType(); - if (cpu != 0 && cpu != CPU_TYPE_ANY && cpu != LLDB_INVALID_CPUTYPE) - { - size_t ocount = 0; - err.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), Error::POSIX); - if (err.Fail() || log) - err.Log(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %zu )", cpu, ocount); - - if (err.Fail() != 0 || ocount != 1) - return LLDB_INVALID_PROCESS_ID; - } - -#endif - - PseudoTerminal pty; - - posix_spawn_file_actions_t file_actions; - err.SetError( ::posix_spawn_file_actions_init (&file_actions), Error::POSIX); - int file_actions_valid = err.Success(); - if (!file_actions_valid || log) - err.Log(log, "::posix_spawn_file_actions_init ( &file_actions )"); - Error stdio_err; - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - if (file_actions_valid) - { - // If the user specified any STDIO files, then use those - if (stdin_path || stdout_path || stderr_path) - { - process->SetSTDIOIsOurs(false); - if (stderr_path != NULL && stderr_path[0]) - { - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDERR_FILENO, stderr_path, O_RDWR, 0), Error::POSIX); - if (stdio_err.Fail() || log) - stdio_err.Log(log, "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDERR_FILENO, path = '%s', oflag = O_RDWR, mode = 0 )", stderr_path); - } - - if (stdin_path != NULL && stdin_path[0]) - { - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDIN_FILENO, stdin_path, O_RDONLY, 0), Error::POSIX); - if (stdio_err.Fail() || log) - stdio_err.Log(log, "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDIN_FILENO, path = '%s', oflag = O_RDONLY, mode = 0 )", stdin_path); - } - - if (stdout_path != NULL && stdout_path[0]) - { - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDOUT_FILENO, stdout_path, O_WRONLY, 0), Error::POSIX); - if (stdio_err.Fail() || log) - stdio_err.Log(log, "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDOUT_FILENO, path = '%s', oflag = O_WRONLY, mode = 0 )", stdout_path); - } - } - else - { - // The user did not specify any STDIO files, use a pseudo terminal. - // Callers can then access the file handles using the - // ProcessMacOSXRemote::ReleaseChildFileDescriptors() function, otherwise - // this class will spawn a thread that tracks STDIO and buffers it. - process->SetSTDIOIsOurs(true); - if (pty.OpenFirstAvailableMaster(O_RDWR, &stdio_err)) - { - const char* slave_name = pty.GetSlaveName(&stdio_err); - if (slave_name == NULL) - slave_name = "/dev/null"; - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDERR_FILENO, slave_name, O_RDWR, 0), Error::POSIX); - if (stdio_err.Fail() || log) - stdio_err.Log(log, "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDERR_FILENO, path = '%s', oflag = O_RDWR, mode = 0 )", slave_name); - - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDIN_FILENO, slave_name, O_RDONLY, 0), Error::POSIX); - if (stdio_err.Fail() || log) - stdio_err.Log(log, "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDIN_FILENO, path = '%s', oflag = O_RDONLY, mode = 0 )", slave_name); - - stdio_err.SetError( ::posix_spawn_file_actions_addopen(&file_actions, STDOUT_FILENO, slave_name, O_WRONLY, 0), Error::POSIX); - if (stdio_err.Fail() || log) - stdio_err.Log(log, "::posix_spawn_file_actions_addopen ( &file_actions, filedes = STDOUT_FILENO, path = '%s', oflag = O_WRONLY, mode = 0 )", slave_name); - } - } - err.SetError( ::posix_spawnp (&pid, path, &file_actions, &attr, (char * const*)argv, (char * const*)envp), Error::POSIX); - if (err.Fail() || log) - err.Log(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", pid, path, &file_actions, &attr, argv, envp); - - if (stdio_err.Success()) - { - // If we have a valid process and we created the STDIO file handles, - // then remember them on our process class so we can spawn a STDIO - // thread and close them when we are done with them. - if (process != NULL && process->STDIOIsOurs()) - { - int master_fd = pty.ReleaseMasterFileDescriptor (); - process->SetChildFileDescriptors (master_fd, master_fd, master_fd); - } - } - } - else - { - err.SetError( ::posix_spawnp (&pid, path, NULL, &attr, (char * const*)argv, (char * const*)envp), Error::POSIX); - if (err.Fail() || log) - err.Log(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", pid, path, NULL, &attr, argv, envp); - } - - // We have seen some cases where posix_spawnp was returning a valid - // looking pid even when an error was returned, so clear it out - if (err.Fail()) - pid = LLDB_INVALID_PROCESS_ID; - - if (file_actions_valid) - { - local_err.SetError( ::posix_spawn_file_actions_destroy (&file_actions), Error::POSIX); - if (local_err.Fail() || log) - local_err.Log(log, "::posix_spawn_file_actions_destroy ( &file_actions )"); - } - - return pid; -} - -lldb::pid_t -ProcessMacOSXRemote::ForkChildForPTraceDebugging -( - const char *path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - ProcessMacOSXRemote* process, - Error &launch_err -) -{ - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - - if (stdin_path || stdout_path || stderr_path) - { - assert(!"TODO: ForkChildForPTraceDebugging doesn't currently support fork/exec with user file handles..."); - } - else - { - - // Use a fork that ties the child process's stdin/out/err to a pseudo - // terminal so we can read it in our ProcessMacOSXRemote::STDIOThread - // as unbuffered io. - PseudoTerminal pty; - pid = pty.Fork(&launch_err); - - if (pid < 0) - { - //-------------------------------------------------------------- - // Error during fork. - //-------------------------------------------------------------- - return pid; - } - else if (pid == 0) - { - //-------------------------------------------------------------- - // Child process - //-------------------------------------------------------------- - ::ptrace (PT_TRACE_ME, 0, 0, 0); // Debug this process - ::ptrace (PT_SIGEXC, 0, 0, 0); // Get BSD signals as mach exceptions - - // If our parent is setgid, lets make sure we don't inherit those - // extra powers due to nepotism. - ::setgid (getgid ()); - - // Let the child have its own process group. We need to execute - // this call in both the child and parent to avoid a race condition - // between the two processes. - ::setpgid (0, 0); // Set the child process group to match its pid - - // Sleep a bit to before the exec call - ::sleep (1); - - // Turn this process into - ::execv (path, (char * const *)argv); - // Exit with error code. Child process should have taken - // over in above exec call and if the exec fails it will - // exit the child process below. - ::exit (127); - } - else - { - //-------------------------------------------------------------- - // Parent process - //-------------------------------------------------------------- - // Let the child have its own process group. We need to execute - // this call in both the child and parent to avoid a race condition - // between the two processes. - ::setpgid (pid, pid); // Set the child process group to match its pid - - if (process != NULL) - { - // Release our master pty file descriptor so the pty class doesn't - // close it and so we can continue to use it in our STDIO thread - int master_fd = pty.ReleaseMasterFileDescriptor (); - process->SetChildFileDescriptors (master_fd, master_fd, master_fd); - } - } - } - return pid; -} - -#if defined (__arm__) - -lldb::pid_t -ProcessMacOSXRemote::SBLaunchForDebug -( - const char *path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - Error &launch_err -) -{ - // Clear out and clean up from any current state - Clear(); - - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path); - - // Fork a child process for debugging - SetState(eStateLaunching); - m_pid = ProcessMacOSXRemote::SBLaunchForDebug(path, argv, envp, this, launch_err); - if (m_pid != 0) - { - m_flags |= eFlagsUsingSBS; - //m_path = path; -// size_t i; -// char const *arg; -// for (i=0; (arg = argv[i]) != NULL; i++) -// m_args.push_back(arg); - m_task.StartExceptionThread(); - StartSTDIOThread(); - SetState (eStateAttaching); - int err = ptrace (PT_ATTACHEXC, m_pid, 0, 0); - if (err == 0) - { - m_flags |= eFlagsAttached; - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "successfully attached to pid %d", m_pid); - } - else - { - SetState (eStateExited); - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "error: failed to attach to pid %d", m_pid); - } - } - return m_pid; -} - -#include <servers/bootstrap.h> -#include "CFBundle.h" -#include "CFData.h" -#include "CFString.h" - -lldb::pid_t -ProcessMacOSXRemote::SBLaunchForDebug -( - const char *app_bundle_path, - char const *argv[], - char const *envp[], - ArchSpec& arch_spec, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - ProcessMacOSXRemote* process, - Error &launch_err -) -{ - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s( '%s', argv, %p)", __FUNCTION__, app_bundle_path, process); - CFAllocatorRef alloc = kCFAllocatorDefault; - if (argv[0] == NULL) - return LLDB_INVALID_PROCESS_ID; - - size_t argc = 0; - // Count the number of arguments - while (argv[argc] != NULL) - argc++; - - // Enumerate the arguments - size_t first_launch_arg_idx = 1; - CFReleaser<CFMutableArrayRef> launch_argv; - - if (argv[first_launch_arg_idx]) - { - size_t launch_argc = argc > 0 ? argc - 1 : 0; - launch_argv.reset (::CFArrayCreateMutable (alloc, launch_argc, &kCFTypeArrayCallBacks)); - size_t i; - char const *arg; - CFString launch_arg; - for (i=first_launch_arg_idx; (i < argc) && ((arg = argv[i]) != NULL); i++) - { - launch_arg.reset(::CFStringCreateWithCString (alloc, arg, kCFStringEncodingUTF8)); - if (launch_arg.get() != NULL) - CFArrayAppendValue(launch_argv.get(), launch_arg.get()); - else - break; - } - } - - // Next fill in the arguments dictionary. Note, the envp array is of the form - // Variable=value but SpringBoard wants a CF dictionary. So we have to convert - // this here. - - CFReleaser<CFMutableDictionaryRef> launch_envp; - - if (envp[0]) - { - launch_envp.reset(::CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); - const char *value; - int name_len; - CFString name_string, value_string; - - for (int i = 0; envp[i] != NULL; i++) - { - value = strstr (envp[i], "="); - - // If the name field is empty or there's no =, skip it. Somebody's messing with us. - if (value == NULL || value == envp[i]) - continue; - - name_len = value - envp[i]; - - // Now move value over the "=" - value++; - - name_string.reset(::CFStringCreateWithBytes(alloc, (const UInt8 *) envp[i], name_len, kCFStringEncodingUTF8, false)); - value_string.reset(::CFStringCreateWithCString(alloc, value, kCFStringEncodingUTF8)); - CFDictionarySetValue (launch_envp.get(), name_string.get(), value_string.get()); - } - } - - CFString stdout_cf_path; - CFString stderr_cf_path; - PseudoTerminal pty; - - if (stdin_path || stdout_path || stderr_path) - { - process->SetSTDIOIsOurs(false); - if (stdout_path) - stdout_cf_path.SetFileSystemRepresentation (stdout_path); - if (stderr_path) - stderr_cf_path.SetFileSystemRepresentation (stderr_path); - } - else - { - process->SetSTDIOIsOurs(true); - PseudoTerminal::Error pty_err = pty.OpenFirstAvailableMaster(O_RDWR); - if (pty_err == PseudoTerminal::success) - { - const char* slave_name = pty.SlaveName(); - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() successfully opened master pty, slave is %s", __FUNCTION__, slave_name); - if (slave_name && slave_name[0]) - { - ::chmod (slave_name, S_IRWXU | S_IRWXG | S_IRWXO); - stdout_cf_path.SetFileSystemRepresentation (slave_name); - stderr_cf_path.(stdout_cf_path); - } - } - } - - if (stdout_cf_path.get() == NULL) - stdout_cf_path.SetFileSystemRepresentation ("/dev/null"); - if (stderr_cf_path.get() == NULL) - stderr_cf_path.SetFileSystemRepresentation ("/dev/null"); - - CFBundle bundle(app_bundle_path); - CFStringRef bundleIDCFStr = bundle.GetIdentifier(); - std::string bundleID; - if (CFString::UTF8(bundleIDCFStr, bundleID) == NULL) - { - struct stat app_bundle_stat; - if (::stat (app_bundle_path, &app_bundle_stat) < 0) - { - launch_err.SetError(errno, Error::POSIX); - launch_err.SetErrorStringWithFormat ("%s: \"%s\".\n", launch_err.AsString(), app_bundle_path); - } - else - { - launch_err.SetError(-1, Error::Generic); - launch_err.SetErrorStringWithFormat ("Failed to extract CFBundleIdentifier from %s.\n", app_bundle_path); - } - return LLDB_INVALID_PROCESS_ID; - } - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() extracted CFBundleIdentifier: %s", __FUNCTION__, bundleID.c_str()); - - - CFData argv_data(NULL); - - if (launch_argv.get()) - { - if (argv_data.Serialize(launch_argv.get(), kCFPropertyListBinaryFormat_v1_0) == NULL) - { - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() error: failed to serialize launch arg array...", __FUNCTION__); - return LLDB_INVALID_PROCESS_ID; - } - } - - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() serialized launch arg array", __FUNCTION__); - - // Find SpringBoard - SBSApplicationLaunchError sbs_error = 0; - sbs_error = SBSLaunchApplication ( bundleIDCFStr, - (CFURLRef)NULL, // openURL - launch_argv.get(), - launch_envp.get(), // CFDictionaryRef environment - stdout_cf_path.get(), - stderr_cf_path.get(), - SBSApplicationLaunchWaitForDebugger | SBSApplicationLaunchUnlockDevice); - - - launch_err.SetError(sbs_error, Error::SpringBoard); - - if (sbs_error == SBSApplicationLaunchErrorSuccess) - { - static const useconds_t pid_poll_interval = 200000; - static const useconds_t pid_poll_timeout = 30000000; - - useconds_t pid_poll_total = 0; - - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - Boolean pid_found = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &pid); - // Poll until the process is running, as long as we are getting valid responses and the timeout hasn't expired - // A return PID of 0 means the process is not running, which may be because it hasn't been (asynchronously) started - // yet, or that it died very quickly (if you weren't using waitForDebugger). - while (!pid_found && pid_poll_total < pid_poll_timeout) - { - usleep (pid_poll_interval); - pid_poll_total += pid_poll_interval; - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() polling Springboard for pid for %s...", __FUNCTION__, bundleID.c_str()); - pid_found = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &pid); - } - - if (pid_found) - { - // If we have a valid process and we created the STDIO file handles, - // then remember them on our process class so we can spawn a STDIO - // thread and close them when we are done with them. - if (process != NULL && process->STDIOIsOurs()) - { - // Release our master pty file descriptor so the pty class doesn't - // close it and so we can continue to use it in our STDIO thread - int master_fd = pty.ReleaseMasterFD(); - process->SetChildFileDescriptors(master_fd, master_fd, master_fd); - } - ProcessMacOSXLog::LogIf (PD_LOG_PROCESS, "%s() => pid = %4.4x", __FUNCTION__, pid); - } - else - { - LogError("failed to lookup the process ID for CFBundleIdentifier %s.", bundleID.c_str()); - } - return pid; - } - - LogError("unable to launch the application with CFBundleIdentifier '%s' sbs_error = %u", bundleID.c_str(), sbs_error); - return LLDB_INVALID_PROCESS_ID; -} - -#endif // #if defined (__arm__) - diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXRemote.h b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXRemote.h deleted file mode 100644 index 01905c6192a..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSXRemote.h +++ /dev/null @@ -1,206 +0,0 @@ -//===-- ProcessMacOSXRemote.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -//---------------------------------------------------------------------- -// -// ProcessMacOSXRemote.h -// liblldb -// -// Created by Greg Clayton on 4/21/09. -// -// -//---------------------------------------------------------------------- - -#ifndef liblldb_ProcessMacOSXRemote_H_ -#define liblldb_ProcessMacOSXRemote_H_ - -// C Includes - -// C++ Includes -#include <list> - -// Other libraries and framework includes -#include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" - -class ThreadMacOSXRemote; - -class ProcessMacOSXRemote : - public Process -{ -public: - friend class ThreadMacOSX; - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ProcessMacOSXRemote(Target& target); - virtual ~DCProcessMacOSXRemote(); - - static Process* CreateInstance (Target& target); - - //------------------------------------------------------------------ - // Check if a given Process - //------------------------------------------------------------------ - virtual bool CanDebug(Target &target); - - //------------------------------------------------------------------ - // Creating a new process, or attaching to an existing one - //------------------------------------------------------------------ - virtual lldb::pid_t DoLaunch (Module* module, - char const *argv[], // Can be NULL - char const *envp[], // Can be NULL - const char *stdin_path, // Can be NULL - const char *stdout_path, // Can be NULL - const char *stderr_path); // Can be NULL - virtual void DidLaunch (); - virtual lldb::pid_t DoAttach (lldb::pid_t pid); - virtual void DidAttach (); - - //------------------------------------------------------------------ - // Process Control - //------------------------------------------------------------------ -// virtual bool WillResume (); - virtual bool DoResume (); -// virtual void DidResume (); - - virtual bool DoHalt (); - virtual bool WillDetach (); - virtual bool DoDetach (); - virtual bool DoKill (int signal); - - virtual bool ShouldStop (); - - //------------------------------------------------------------------ - // Process Queries - //------------------------------------------------------------------ - virtual bool IsAlive (); - virtual bool IsRunning (); - virtual lldb::addr_t GetImageInfoAddress(); - - //------------------------------------------------------------------ - // Process Memory - //------------------------------------------------------------------ - virtual size_t DoReadMemory (lldb::addr_t addr, void *buf, size_t size); - virtual size_t DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size); - - //------------------------------------------------------------------ - // Process STDIO - //------------------------------------------------------------------ - virtual size_t GetSTDOUT (char *buf, size_t buf_size); - virtual size_t GetSTDERR (char *buf, size_t buf_size); - - //---------------------------------------------------------------------- - // Process Breakpoints - //---------------------------------------------------------------------- - virtual size_t - GetSoftwareBreakpointTrapOpcode (lldb::BreakpointSite *bp_site); - - //---------------------------------------------------------------------- - // Process Breakpoints - //---------------------------------------------------------------------- - virtual bool - EnableBreakpoint (lldb::BreakpointSite *bp_site); - - virtual bool - DisableBreakpoint (lldb::BreakpointSite *bp_site); - - //---------------------------------------------------------------------- - // Process Watchpoints - //---------------------------------------------------------------------- - virtual bool EnableWatchpoint (WatchpointLocation *wp_loc); - virtual bool DisableWatchpoint (WatchpointLocation *wp_loc); - - //------------------------------------------------------------------ - // Thread Queries - //------------------------------------------------------------------ - virtual Thread * GetCurrentThread (); - virtual bool SetCurrentThread (lldb::tid_t tid); - virtual Thread * GetThreadAtIndex (uint32_t idx); - virtual Thread * GetThreadByID (lldb::tid_t tid); - virtual size_t GetNumThreads (); - - virtual ByteOrder GetByteOrder () const; - - virtual DynamicLoader * - GetDynamicLoader (); - -protected: - Flags m_flags; // Process specific flags (see eFlags enums) - ArchSpec m_arch_spec; - std::auto_ptr<DynamicLoader> m_dynamic_loader_ap; - ByteOrder m_byte_order; - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - bool - ProcessIDIsValid ( ) const; - - bool - IsRunning ( State state ) - { - return state == eStateRunning || IsStepping(state); - } - - bool - IsStepping ( State state) - { - return state == eStateStepping; - } - bool - CanResume ( State state) - { - return state == eStateStopped; - } - - ArchSpec& - GetArchSpec() - { - return m_arch_spec; - } - const ArchSpec& - GetArchSpec() const - { - return m_arch_spec; - } - - enum - { - eFlagsNone = 0, - eFlagsAttached = (1 << 0), - eFlagsUsingSBS = (1 << 1) - }; - - void - Clear ( ); - - Flags & - GetFlags () - { - return m_flags; - } - - const Flags & - GetFlags () const - { - return m_flags; - } - - uint32_t - UpdateThreadListIfNeeded (); - -private: - //------------------------------------------------------------------ - // For ProcessMacOSXRemote only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (ProcessMacOSXRemote); - -}; - -#endif // liblldb_ProcessMacOSXRemote_H_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp deleted file mode 100644 index 51991dad770..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//===-- RegisterContextMach_arm.cpp -----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "RegisterContextMach_arm.h" - -// C Includes -#include <mach/mach_types.h> -#include <mach/thread_act.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes -//#include "ProcessMacOSXLog.h" - -using namespace lldb; -using namespace lldb_private; - - -RegisterContextMach_arm::RegisterContextMach_arm(Thread &thread, uint32_t concrete_frame_idx) : - RegisterContextDarwin_arm (thread, concrete_frame_idx) -{ -} - -RegisterContextMach_arm::~RegisterContextMach_arm() -{ -} - -int -RegisterContextMach_arm::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) -{ - mach_msg_type_number_t count = GPRWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count); -} - -int -RegisterContextMach_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) -{ - mach_msg_type_number_t count = FPUWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count); -} - -int -RegisterContextMach_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) -{ - mach_msg_type_number_t count = EXCWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count); -} - -int -RegisterContextMach_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) -{ - mach_msg_type_number_t count = DBGWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&dbg, &count); -} - -int -RegisterContextMach_arm::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount); -} - -int -RegisterContextMach_arm::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount); -} - -int -RegisterContextMach_arm::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount); -} - -int -RegisterContextMach_arm::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&dbg, DBGWordCount); -} - - diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h deleted file mode 100644 index bf2f06ce9d8..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h +++ /dev/null @@ -1,56 +0,0 @@ -//===-- RegisterContextMach_arm.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_RegisterContextMach_arm_h_ -#define liblldb_RegisterContextMach_arm_h_ - -// C Includes - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h" - -class RegisterContextMach_arm : public RegisterContextDarwin_arm -{ -public: - - RegisterContextMach_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - - virtual - ~RegisterContextMach_arm(); - -protected: - - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr); - - int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu); - - int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc); - - int - DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg); - - int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr); - - int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu); - - int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc); - - int - DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg); -}; - -#endif // liblldb_RegisterContextMach_arm_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp deleted file mode 100644 index 62b50956678..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//===-- RegisterContextMach_i386.cpp ----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -// C Includes -#include <mach/thread_act.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "RegisterContextMach_i386.h" - -using namespace lldb; -using namespace lldb_private; - - -RegisterContextMach_i386::RegisterContextMach_i386(Thread &thread, uint32_t concrete_frame_idx) : - RegisterContextDarwin_i386 (thread, concrete_frame_idx) -{ -} - -RegisterContextMach_i386::~RegisterContextMach_i386() -{ -} - -int -RegisterContextMach_i386::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) -{ - mach_msg_type_number_t count = GPRWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count); -} - -int -RegisterContextMach_i386::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) -{ - mach_msg_type_number_t count = FPUWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count); -} - -int -RegisterContextMach_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) -{ - mach_msg_type_number_t count = EXCWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count); -} - -int -RegisterContextMach_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount); -} - -int -RegisterContextMach_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount); -} - -int -RegisterContextMach_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount); -} - - diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h deleted file mode 100644 index 59d0b0b2920..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h +++ /dev/null @@ -1,49 +0,0 @@ -//===-- RegisterContextMach_i386.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_RegisterContextMach_i386_h_ -#define liblldb_RegisterContextMach_i386_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h" - -class RegisterContextMach_i386 : public RegisterContextDarwin_i386 -{ -public: - - RegisterContextMach_i386(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - - virtual - ~RegisterContextMach_i386(); - -protected: - - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr); - - int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu); - - int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc); - - int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr); - - int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu); - - int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc); -}; - -#endif // liblldb_RegisterContextMach_i386_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp deleted file mode 100644 index 8dab2e54206..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp +++ /dev/null @@ -1,70 +0,0 @@ -//===-- RegisterContextMach_x86_64.cpp --------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -// C Includes -#include <mach/thread_act.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "RegisterContextMach_x86_64.h" - -using namespace lldb; -using namespace lldb_private; - - -RegisterContextMach_x86_64::RegisterContextMach_x86_64(Thread &thread, uint32_t concrete_frame_idx) : -RegisterContextDarwin_x86_64 (thread, concrete_frame_idx) -{ -} - -RegisterContextMach_x86_64::~RegisterContextMach_x86_64() -{ -} - -int -RegisterContextMach_x86_64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) -{ - mach_msg_type_number_t count = GPRWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count); -} - -int -RegisterContextMach_x86_64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) -{ - mach_msg_type_number_t count = FPUWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count); -} - -int -RegisterContextMach_x86_64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) -{ - mach_msg_type_number_t count = EXCWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count); -} - -int -RegisterContextMach_x86_64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount); -} - -int -RegisterContextMach_x86_64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount); -} - -int -RegisterContextMach_x86_64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount); -} - diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h deleted file mode 100644 index 26b83c44adf..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h +++ /dev/null @@ -1,49 +0,0 @@ -//===-- RegisterContextMach_x86_64.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_RegisterContextMach_x86_64_h_ -#define liblldb_RegisterContextMach_x86_64_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h" - -class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64 -{ -public: - - RegisterContextMach_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - - virtual - ~RegisterContextMach_x86_64(); - -protected: - - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr); - - int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu); - - int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc); - - int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr); - - int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu); - - int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc); -}; - -#endif // liblldb_RegisterContextMach_x86_64_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp deleted file mode 100644 index 08df10c1913..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp +++ /dev/null @@ -1,683 +0,0 @@ -//===-- ThreadMacOSX.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -#include "ThreadMacOSX.h" - -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Target/Target.h" - -#include "ProcessMacOSX.h" -#include "ProcessMacOSXLog.h" -#include "MachThreadContext.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Breakpoint/WatchpointLocation.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Target/Unwind.h" -#include "UnwindMacOSXFrameBackchain.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// Thread Registers -//---------------------------------------------------------------------- - -ThreadMacOSX::ThreadMacOSX (ProcessMacOSX &process, lldb::tid_t tid) : - Thread(process, tid), - m_fp_pc_pairs(), - m_basic_info(), - m_suspend_count(0), - m_stop_exception(), - m_context() -{ - ProcessMacOSX::CreateArchCalback create_arch_callback = process.GetArchCreateCallback(); - assert(create_arch_callback != NULL); - m_context.reset(create_arch_callback(process.GetArchSpec(), *this)); - assert(m_context.get() != NULL); - m_context->InitializeInstance(); - ::memset (&m_basic_info, 0, sizeof (m_basic_info)); - ::memset (&m_ident_info, 0, sizeof (m_ident_info)); - ::memset (&m_proc_threadinfo, 0, sizeof (m_proc_threadinfo)); - ProcessMacOSXLog::LogIf(PD_LOG_THREAD | PD_LOG_VERBOSE, "ThreadMacOSX::ThreadMacOSX ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID()); -} - -ThreadMacOSX::~ThreadMacOSX () -{ - DestroyThread(); -} - -#if defined (__i386__) || defined (__x86_64__) - #define MACH_SOFTWARE_BREAKPOINT_DATA_0 EXC_I386_BPT - #define MACH_TRAP_DATA_0 EXC_I386_SGL -#elif defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) - #define MACH_SOFTWARE_BREAKPOINT_DATA_0 EXC_PPC_BREAKPOINT - -#elif defined (__arm__) - #define MACH_SOFTWARE_BREAKPOINT_DATA_0 EXC_ARM_BREAKPOINT -#endif - - -StopInfoSP -ThreadMacOSX::GetPrivateStopReason () -{ - if (m_actual_stop_info_sp.get() == NULL || m_actual_stop_info_sp->IsValid() == false) - m_actual_stop_info_sp = GetStopException().GetStopInfo(*this); - return m_actual_stop_info_sp; -} - -const char * -ThreadMacOSX::GetInfo () -{ - return GetBasicInfoAsString(); -} - -bool -ThreadMacOSX::GetIdentifierInfo () -{ -#ifdef THREAD_IDENTIFIER_INFO_COUNT - if (m_ident_info.thread_id == 0) - { - mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; - return ::thread_info (GetID(), THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count) == KERN_SUCCESS; - } -#else - //m_error.SetErrorString("Thread_info doesn't support THREAD_IDENTIFIER_INFO."); -#endif - - return false; -} - -const char * -ThreadMacOSX::GetDispatchQueueName() -{ - if (GetIdentifierInfo ()) - { - if (m_ident_info.dispatch_qaddr == 0) - return NULL; - - uint8_t memory_buffer[8]; - addr_t dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS; - DataExtractor data (memory_buffer, sizeof(memory_buffer), - m_process.GetTarget().GetArchitecture().GetByteOrder(), - m_process.GetTarget().GetArchitecture().GetAddressByteSize()); - static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets"); - const Symbol *dispatch_queue_offsets_symbol = NULL; - ModuleSP module_sp(m_process.GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false), NULL, NULL)); - if (module_sp) - dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData); - - if (dispatch_queue_offsets_symbol == NULL) - { - module_sp = m_process.GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false), NULL, NULL); - if (module_sp) - dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData); - } - if (dispatch_queue_offsets_symbol) - dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetValue().GetLoadAddress(&m_process.GetTarget()); - - if (dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS) - return NULL; - - // Excerpt from src/queue_private.h - struct dispatch_queue_offsets_s - { - uint16_t dqo_version; - uint16_t dqo_label; - uint16_t dqo_label_size; - } dispatch_queue_offsets; - - Error error; - if (m_process.ReadMemory (dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets)) - { - uint32_t data_offset = 0; - if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t))) - { - if (m_process.ReadMemory (m_ident_info.dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize()) - { - data_offset = 0; - lldb::addr_t queue_addr = data.GetAddress(&data_offset); - lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label; - const size_t chunk_size = 32; - uint32_t label_pos = 0; - m_dispatch_queue_name.resize(chunk_size, '\0'); - while (1) - { - size_t bytes_read = m_process.ReadMemory (label_addr + label_pos, &m_dispatch_queue_name[label_pos], chunk_size, error); - - if (bytes_read <= 0) - break; - - if (m_dispatch_queue_name.find('\0', label_pos) != std::string::npos) - break; - label_pos += bytes_read; - } - m_dispatch_queue_name.erase(m_dispatch_queue_name.find('\0')); - } - } - } - } - - if (m_dispatch_queue_name.empty()) - return NULL; - return m_dispatch_queue_name.c_str(); -} - -const char * -ThreadMacOSX::GetName () -{ - if (GetIdentifierInfo ()) - ::proc_pidinfo (m_process.GetID(), PROC_PIDTHREADINFO, m_ident_info.thread_handle, &m_proc_threadinfo, sizeof (m_proc_threadinfo)); - - // No thread name, lets return the queue name instead - if (m_proc_threadinfo.pth_name[0] == '\0') - return GetDispatchQueueName(); - - // Return the thread name if there was one - if (m_proc_threadinfo.pth_name[0]) - return m_proc_threadinfo.pth_name; - return NULL; -} - -bool -ThreadMacOSX::WillResume (StateType resume_state) -{ - ThreadWillResume(resume_state); - Thread::WillResume(resume_state); - return true; -} - -void -ThreadMacOSX::RefreshStateAfterStop() -{ - // Invalidate all registers in our register context - GetRegisterContext()->InvalidateIfNeeded (false); - - m_context->RefreshStateAfterStop(); - - // We may have suspended this thread so the primary thread could step - // without worrying about race conditions, so lets restore our suspend - // count. - RestoreSuspendCount(); - - // Update the basic information for a thread for suspend count reasons. - ThreadMacOSX::GetBasicInfo(GetID(), &m_basic_info); - m_suspend_count = m_basic_info.suspend_count; - m_basic_info_string.clear(); -} - -Unwind * -ThreadMacOSX::GetUnwinder () -{ - if (m_unwinder_ap.get() == NULL) - { - const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ()); -#if 0 // Not sure this is the right thing to do for native, but this will all go away with Jason's new - // unwinder anyway... - if (target_arch == ArchSpec("x86_64") || target_arch == ArchSpec("i386")) - { - m_unwinder_ap.reset (new UnwindLibUnwind (*this, GetGDBProcess().GetLibUnwindAddressSpace())); - } - else -#endif - { - m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); - } - } - return m_unwinder_ap.get(); -} - - -void -ThreadMacOSX::ClearStackFrames () -{ - m_fp_pc_pairs.clear(); - Thread::ClearStackFrames(); -} - - - -int32_t -ThreadMacOSX::Suspend() -{ - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_THREAD)); - if (log && log->GetMask().Test(PD_LOG_VERBOSE)) - log->Printf ("ThreadMacOSX::%s ( )", __FUNCTION__); - lldb::tid_t tid = GetID (); - if (ThreadIDIsValid(tid)) - { - Error err(::thread_suspend (tid), eErrorTypeMachKernel); - if (err.Success()) - m_suspend_count++; - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_THREAD); - if (log || err.Fail()) - err.PutToLog(log.get(), "::thread_suspend (%4.4x)", tid); - } - return GetSuspendCount(); -} - -int32_t -ThreadMacOSX::Resume() -{ - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_THREAD)); - if (log && log->GetMask().Test(PD_LOG_VERBOSE)) - log->Printf ("ThreadMacOSX::%s ()", __FUNCTION__); - lldb::tid_t tid = GetID (); - if (ThreadIDIsValid(tid)) - { - while (m_suspend_count > 0) - { - Error err(::thread_resume (tid), eErrorTypeMachKernel); - if (err.Success()) - m_suspend_count--; - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_THREAD); - if (log || err.Fail()) - err.PutToLog(log.get(), "::thread_resume (%4.4x)", tid); - } - } - return GetSuspendCount(); -} - -bool -ThreadMacOSX::RestoreSuspendCount() -{ - LogSP log (ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_THREAD)); - if (log && log->GetMask().Test(PD_LOG_VERBOSE)) - log->Printf ("ThreadMacOSX::%s ( )", __FUNCTION__); - Error err; - lldb::tid_t tid = GetID (); - if (ThreadIDIsValid(tid) == false) - return false; - else if (m_suspend_count > m_basic_info.suspend_count) - { - while (m_suspend_count > m_basic_info.suspend_count) - { - err = ::thread_resume (tid); - if (err.Success()) - --m_suspend_count; - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_THREAD); - if (log || err.Fail()) - err.PutToLog(log.get(), "::thread_resume (%4.4x)", tid); - } - } - else if (m_suspend_count < m_basic_info.suspend_count) - { - while (m_suspend_count < m_basic_info.suspend_count) - { - err = ::thread_suspend (tid); - if (err.Success()) - --m_suspend_count; - log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_THREAD); - if (log || err.Fail()) - err.PutToLog(log.get(), "::thread_suspend (%4.4x)", tid); - } - } - return m_suspend_count == m_basic_info.suspend_count; -} - - -const char * -ThreadMacOSX::GetBasicInfoAsString () -{ - if (m_basic_info_string.empty()) - { - StreamString sstr; - struct thread_basic_info basicInfo; - - lldb::tid_t tid = GetID (); - if (GetBasicInfo(tid, &basicInfo)) - { -// char run_state_str[32]; -// size_t run_state_str_size = sizeof(run_state_str); -// switch (basicInfo.run_state) -// { -// case TH_STATE_RUNNING: strncpy(run_state_str, "running", run_state_str_size); break; -// case TH_STATE_STOPPED: strncpy(run_state_str, "stopped", run_state_str_size); break; -// case TH_STATE_WAITING: strncpy(run_state_str, "waiting", run_state_str_size); break; -// case TH_STATE_UNINTERRUPTIBLE: strncpy(run_state_str, "uninterruptible", run_state_str_size); break; -// case TH_STATE_HALTED: strncpy(run_state_str, "halted", run_state_str_size); break; -// default: snprintf(run_state_str, run_state_str_size, "%d", basicInfo.run_state); break; // ??? -// } - float user = (float)basicInfo.user_time.seconds + (float)basicInfo.user_time.microseconds / 1000000.0f; - float system = (float)basicInfo.user_time.seconds + (float)basicInfo.user_time.microseconds / 1000000.0f; - sstr.Printf("Thread 0x%4.4x: user=%f system=%f cpu=%d sleep_time=%d", - InferiorThreadID(), - user, - system, - basicInfo.cpu_usage, - basicInfo.sleep_time); - m_basic_info_string.assign (sstr.GetData(), sstr.GetSize()); - } - } - if (m_basic_info_string.empty()) - return NULL; - return m_basic_info_string.c_str(); -} - - -//const uint8_t * -//ThreadMacOSX::SoftwareBreakpointOpcode (size_t break_op_size) const -//{ -// return m_context->SoftwareBreakpointOpcode(break_op_size); -//} - - -lldb::tid_t -ThreadMacOSX::InferiorThreadID() const -{ - mach_msg_type_number_t i; - mach_port_name_array_t names; - mach_port_type_array_t types; - mach_msg_type_number_t ncount, tcount; - lldb::tid_t inferior_tid = LLDB_INVALID_THREAD_ID; - task_t my_task = ::mach_task_self(); - task_t task = GetMacOSXProcess().Task().GetTaskPort(); - - kern_return_t kret = ::mach_port_names (task, &names, &ncount, &types, &tcount); - if (kret == KERN_SUCCESS) - { - lldb::tid_t tid = GetID (); - - for (i = 0; i < ncount; i++) - { - mach_port_t my_name; - mach_msg_type_name_t my_type; - - kret = ::mach_port_extract_right (task, names[i], MACH_MSG_TYPE_COPY_SEND, &my_name, &my_type); - if (kret == KERN_SUCCESS) - { - ::mach_port_deallocate (my_task, my_name); - if (my_name == tid) - { - inferior_tid = names[i]; - break; - } - } - } - // Free up the names and types - ::vm_deallocate (my_task, (vm_address_t) names, ncount * sizeof (mach_port_name_t)); - ::vm_deallocate (my_task, (vm_address_t) types, tcount * sizeof (mach_port_type_t)); - } - return inferior_tid; -} - -bool -ThreadMacOSX::GetBasicInfo(lldb::tid_t thread, struct thread_basic_info *basicInfoPtr) -{ - if (ThreadIDIsValid(thread)) - { - unsigned int info_count = THREAD_BASIC_INFO_COUNT; - kern_return_t err = ::thread_info (thread, THREAD_BASIC_INFO, (thread_info_t) basicInfoPtr, &info_count); - if (err == KERN_SUCCESS) - return true; - } - ::memset (basicInfoPtr, 0, sizeof (struct thread_basic_info)); - return false; -} - - -bool -ThreadMacOSX::ThreadIDIsValid (lldb::tid_t thread) -{ - return thread != 0; -} - -void -ThreadMacOSX::Dump(Log *log, uint32_t index) -{ - const char * thread_run_state = NULL; - - switch (m_basic_info.run_state) - { - case TH_STATE_RUNNING: thread_run_state = "running"; break; // 1 thread is running normally - case TH_STATE_STOPPED: thread_run_state = "stopped"; break; // 2 thread is stopped - case TH_STATE_WAITING: thread_run_state = "waiting"; break; // 3 thread is waiting normally - case TH_STATE_UNINTERRUPTIBLE: thread_run_state = "uninter"; break; // 4 thread is in an uninterruptible wait - case TH_STATE_HALTED: thread_run_state = "halted "; break; // 5 thread is halted at a - default: thread_run_state = "???"; break; - } - - RegisterContext *reg_context = GetRegisterContext().get(); - log->Printf ("thread[%u] %4.4x (%u): pc: 0x%8.8llx sp: 0x%8.8llx breakID: %d user: %d.%06.6d system: %d.%06.6d cpu: %d policy: %d run_state: %d (%s) flags: %d suspend_count: %d (current %d) sleep_time: %d", - index, - GetID (), - reg_context->GetPC (LLDB_INVALID_ADDRESS), - reg_context->GetSP (LLDB_INVALID_ADDRESS), - m_basic_info.user_time.seconds, m_basic_info.user_time.microseconds, - m_basic_info.system_time.seconds, m_basic_info.system_time.microseconds, - m_basic_info.cpu_usage, - m_basic_info.policy, - m_basic_info.run_state, - thread_run_state, - m_basic_info.flags, - m_basic_info.suspend_count, m_suspend_count, - m_basic_info.sleep_time); - //DumpRegisterState(0); -} - -void -ThreadMacOSX::ThreadWillResume (StateType resume_state) -{ - // Update the thread state to be the state we wanted when the task resumes - SetState (resume_state); - switch (resume_state) - { - case eStateSuspended: - Suspend(); - break; - - case eStateRunning: - case eStateStepping: - Resume(); - break; - default: - break; - } - m_context->ThreadWillResume(); -} - -void -ThreadMacOSX::DidResume () -{ - // TODO: cache current stack frames for next time in case we can match things up?? - ClearStackFrames(); - m_stop_exception.Clear(); - Thread::DidResume(); -} - -bool -ThreadMacOSX::ShouldStop(bool &step_more) -{ -// TODO: REmove this after all is working, Process should be managing this -// for us. -// -// // See if this thread is at a breakpoint? -// lldb::user_id_t breakID = CurrentBreakpoint(); -// -// if (LLDB_BREAK_ID_IS_VALID(breakID)) -// { -// // This thread is sitting at a breakpoint, ask the breakpoint -// // if we should be stopping here. -// if (Process()->Breakpoints().ShouldStop(ProcessID(), ThreadID(), breakID)) -// return true; -// else -// { -// // The breakpoint said we shouldn't stop, but we may have gotten -// // a signal or the user may have requested to stop in some other -// // way. Stop if we have a valid exception (this thread won't if -// // another thread was the reason this process stopped) and that -// // exception, is NOT a breakpoint exception (a common case would -// // be a SIGINT signal). -// if (GetStopException().IsValid() && !GetStopException().IsBreakpoint()) -// return true; -// } -// } -// else -// { - if (m_context->StepNotComplete()) - { - step_more = true; - return false; - } -// // The thread state is used to let us know what the thread was -// // trying to do. ThreadMacOSX::ThreadWillResume() will set the -// // thread state to various values depending if the thread was -// // the current thread and if it was to be single stepped, or -// // resumed. -// if (GetState() == eStateRunning) -// { -// // If our state is running, then we should continue as we are in -// // the process of stepping over a breakpoint. -// return false; -// } -// else -// { -// // Stop if we have any kind of valid exception for this -// // thread. -// if (GetStopException().IsValid()) -// return true; -// } -// } -// return false; - return true; -} - -bool -ThreadMacOSX::NotifyException(MachException::Data& exc) -{ - if (m_stop_exception.IsValid()) - { - // We may have more than one exception for a thread, but we need to - // only remember the one that we will say is the reason we stopped. - // We may have been single stepping and also gotten a signal exception, - // so just remember the most pertinent one. - if (m_stop_exception.IsBreakpoint()) - m_stop_exception = exc; - } - else - { - m_stop_exception = exc; - } -// bool handled = - m_context->NotifyException(exc); -// if (!handled) -// { -// handled = true; -// lldb::addr_t pc = GetPC(); -// lldb::user_id_t breakID = m_process.Breakpoints().FindIDCyAddress(pc); -// SetCurrentBreakpoint(breakID); -// switch (exc.exc_type) -// { -// case EXC_BAD_ACCESS: -// break; -// case EXC_BAD_INSTRUCTION: -// break; -// case EXC_ARITHMETIC: -// break; -// case EXC_EMULATION: -// break; -// case EXC_SOFTWARE: -// break; -// case EXC_BREAKPOINT: -// break; -// case EXC_SYSCALL: -// break; -// case EXC_MACH_SYSCALL: -// break; -// case EXC_RPC_ALERT: -// break; -// } -// } -// return handled; - return true; -} - -RegisterContextSP -ThreadMacOSX::GetRegisterContext () -{ - if (m_reg_context_sp.get() == NULL) - m_reg_context_sp = CreateRegisterContextForFrame (NULL); - return m_reg_context_sp; -} - -RegisterContextSP -ThreadMacOSX::CreateRegisterContextForFrame (StackFrame *frame) -{ - return m_context->CreateRegisterContext (frame); -} - -uint32_t -ThreadMacOSX::SetHardwareBreakpoint (const BreakpointSite *bp) -{ - if (bp != NULL) - return GetRegisterContext()->SetHardwareBreakpoint(bp->GetLoadAddress(), bp->GetByteSize()); - return LLDB_INVALID_INDEX32; -} - -uint32_t -ThreadMacOSX::SetHardwareWatchpoint (const WatchpointLocation *wp) -{ - if (wp != NULL) - return GetRegisterContext()->SetHardwareWatchpoint(wp->GetLoadAddress(), wp->GetByteSize(), wp->WatchpointRead(), wp->WatchpointWrite()); - return LLDB_INVALID_INDEX32; -} - - -bool -ThreadMacOSX::ClearHardwareBreakpoint (const BreakpointSite *bp) -{ - if (bp != NULL && bp->IsHardware()) - return GetRegisterContext()->ClearHardwareBreakpoint(bp->GetHardwareIndex()); - return false; -} - -bool -ThreadMacOSX::ClearHardwareWatchpoint (const WatchpointLocation *wp) -{ - if (wp != NULL && wp->IsHardware()) - return GetRegisterContext()->ClearHardwareWatchpoint(wp->GetHardwareIndex()); - return false; -} - -size_t -ThreadMacOSX::GetStackFrameData(std::vector<std::pair<lldb::addr_t, lldb::addr_t> >& fp_pc_pairs) -{ - lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); - return m_context->GetStackFrameData(frame_sp.get(), fp_pc_pairs); -} - - -//void -//ThreadMacOSX::NotifyBreakpointChanged (const BreakpointSite *bp) -//{ -// if (bp) -// { -// lldb::user_id_t breakID = bp->GetID(); -// if (bp->IsEnabled()) -// { -// if (bp->Address() == GetPC()) -// { -// SetCurrentBreakpoint(breakID); -// } -// } -// else -// { -// if (CurrentBreakpoint() == breakID) -// { -// SetCurrentBreakpoint(LLDB_INVALID_BREAK_ID); -// } -// } -// } -//} -// - - diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.h b/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.h deleted file mode 100644 index 25ca7c88b49..00000000000 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.h +++ /dev/null @@ -1,150 +0,0 @@ -//===-- ThreadMacOSX.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_ThreadMacOSX_h_ -#define liblldb_ThreadMacOSX_h_ - -#include <libproc.h> - -#include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" -#include "MachException.h" - -class ProcessMacOSX; -class MachThreadContext; - -class ThreadMacOSX : public lldb_private::Thread -{ -public: - ThreadMacOSX (ProcessMacOSX &process, lldb::tid_t tid); - - virtual - ~ThreadMacOSX (); - - virtual bool - WillResume (lldb::StateType resume_state); - - virtual void - RefreshStateAfterStop(); - - virtual const char * - GetInfo (); - - virtual const char * - GetName (); - - virtual lldb::RegisterContextSP - GetRegisterContext (); - - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - virtual void - ClearStackFrames (); - - ProcessMacOSX & - GetMacOSXProcess () - { - return (ProcessMacOSX &)m_process; - } - - const ProcessMacOSX & - GetMacOSXProcess () const - { - return (ProcessMacOSX &)m_process; - } - - void - Dump (lldb_private::Log *log, uint32_t index); - - lldb::tid_t - InferiorThreadID () const; - - static bool - ThreadIDIsValid (lldb::tid_t thread); - - int32_t - Resume (); - - int32_t - Suspend (); - - int32_t - GetSuspendCount () const { return m_suspend_count; } - - bool - RestoreSuspendCount (); - - uint32_t - SetHardwareBreakpoint (const lldb_private::BreakpointSite *bp); - - uint32_t - SetHardwareWatchpoint (const lldb_private::WatchpointLocation *wp); - - bool - ClearHardwareBreakpoint (const lldb_private::BreakpointSite *bp); - - bool - ClearHardwareWatchpoint (const lldb_private::WatchpointLocation *wp); - - void - ThreadWillResume (lldb::StateType resume_state); - - virtual void - DidResume (); - - bool - ShouldStop (bool &step_more); - - bool - NotifyException (MachException::Data& exc); - - const MachException::Data& - GetStopException () { return m_stop_exception; } - - const char * - GetBasicInfoAsString (); - - size_t - GetStackFrameData (std::vector<std::pair<lldb::addr_t, lldb::addr_t> >& fp_pc_pairs); - - virtual lldb::StopInfoSP - GetPrivateStopReason (); - -protected: - bool - GetIdentifierInfo (); - - const char * - GetDispatchQueueName(); - - static bool - GetBasicInfo (lldb::tid_t threadID, struct thread_basic_info *basic_info); - - virtual lldb_private::Unwind * - GetUnwinder (); - - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - std::vector<std::pair<lldb::addr_t, lldb::addr_t> > m_fp_pc_pairs; - struct thread_basic_info m_basic_info; // Basic information for a thread used to see if a thread is valid - std::string m_basic_info_string;// Basic thread info as a C string. -#ifdef THREAD_IDENTIFIER_INFO_COUNT - thread_identifier_info_data_t m_ident_info; - struct proc_threadinfo m_proc_threadinfo; - std::string m_dispatch_queue_name; -#endif - int32_t m_suspend_count; // The current suspend count - MachException::Data m_stop_exception; // The best exception that describes why this thread is stopped - std::auto_ptr<MachThreadContext> m_context; // The arch specific thread context for this thread (register state and more) - -}; - -#endif // liblldb_ThreadMacOSX_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index d72ec6733b4..99341ac1142 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -27,7 +27,6 @@ // Project includes #include "ARM_GCC_Registers.h" #include "ARM_DWARF_Registers.h" -#include "ProcessMacOSXLog.h" using namespace lldb; using namespace lldb_private; @@ -980,7 +979,7 @@ RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints () // Zero is reserved for the BRP count, so don't increment it if it is zero if (g_num_supported_hw_breakpoints > 0) g_num_supported_hw_breakpoints++; - ProcessMacOSXLog::LogIf(PD_LOG_THREAD, "DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_breakpoints); +// if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_breakpoints); } return g_num_supported_hw_breakpoints; @@ -1025,13 +1024,13 @@ RegisterContextDarwin_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size byte_addr_select | // Set the correct byte address select so we only trigger on the correct opcode S_USER | // Which modes should this breakpoint stop in? BCR_ENABLE; // Enable this hardware breakpoint - ProcessMacOSXLog::LogIf(PD_LOG_BREAKPOINTS, "RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)", - addr, - size, - i, - i, - dbg.bvr[i], - dbg.bcr[i]); +// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)", +// addr, +// size, +// i, +// i, +// dbg.bvr[i], +// dbg.bcr[i]); } else if (size == 4) { @@ -1040,25 +1039,25 @@ RegisterContextDarwin_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA S_USER | // Which modes should this breakpoint stop in? BCR_ENABLE; // Enable this hardware breakpoint - ProcessMacOSXLog::LogIf(PD_LOG_BREAKPOINTS, "RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)", - addr, - size, - i, - i, - dbg.bvr[i], - dbg.bcr[i]); +// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)", +// addr, +// size, +// i, +// i, +// dbg.bvr[i], +// dbg.bcr[i]); } kret = WriteDBG(); - ProcessMacOSXLog::LogIf(PD_LOG_BREAKPOINTS, "RegisterContextDarwin_arm::EnableHardwareBreakpoint() WriteDBG() => 0x%8.8x.", kret); +// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint() WriteDBG() => 0x%8.8x.", kret); if (kret == KERN_SUCCESS) return i; } - else - { - ProcessMacOSXLog::LogIf(PD_LOG_BREAKPOINTS, "RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size); - } +// else +// { +// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size); +// } } return LLDB_INVALID_INDEX32; @@ -1075,12 +1074,12 @@ RegisterContextDarwin_arm::ClearHardwareBreakpoint (uint32_t hw_index) if (hw_index < num_hw_points) { dbg.bcr[hw_index] = 0; - ProcessMacOSXLog::LogIf(PD_LOG_BREAKPOINTS, "RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x BCR%u = 0x%8.8x", - hw_index, - hw_index, - dbg.bvr[hw_index], - hw_index, - dbg.bcr[hw_index]); +// if (log) log->Printf ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x BCR%u = 0x%8.8x", +// hw_index, +// hw_index, +// dbg.bvr[hw_index], +// hw_index, +// dbg.bcr[hw_index]); kret = WriteDBG(); @@ -1106,7 +1105,7 @@ RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints () uint32_t register_DBGDIDR; asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR)); g_num_supported_hw_watchpoints = bits(register_DBGDIDR, 31, 28) + 1; - ProcessMacOSXLog::LogIf(PD_LOG_THREAD, "DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_watchpoints); +// if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_watchpoints); } return g_num_supported_hw_watchpoints; #else @@ -1119,7 +1118,7 @@ RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints () uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write) { - ProcessMacOSXLog::LogIf(PD_LOG_WATCHPOINTS, "RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write); +// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write); const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); @@ -1140,10 +1139,10 @@ RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size // until the next 4 byte boundary and we need to make sure we can properly // encode this. uint32_t addr_word_offset = addr % 4; - ProcessMacOSXLog::LogIf(PD_LOG_WATCHPOINTS, "RegisterContextDarwin_arm::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset); +// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset); uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; - ProcessMacOSXLog::LogIf(PD_LOG_WATCHPOINTS, "RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask); +// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask); if (byte_mask > 0xfu) return LLDB_INVALID_INDEX32; @@ -1175,14 +1174,14 @@ RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size WCR_ENABLE; // Enable this watchpoint; kret = WriteDBG(); - ProcessMacOSXLog::LogIf(PD_LOG_WATCHPOINTS, "RegisterContextDarwin_arm::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret); +// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret); if (kret == KERN_SUCCESS) return i; } else { - ProcessMacOSXLog::LogIf(PD_LOG_WATCHPOINTS, "RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); +// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); } } return LLDB_INVALID_INDEX32; @@ -1199,12 +1198,12 @@ RegisterContextDarwin_arm::ClearHardwareWatchpoint (uint32_t hw_index) if (hw_index < num_hw_points) { dbg.wcr[hw_index] = 0; - ProcessMacOSXLog::LogIf(PD_LOG_WATCHPOINTS, "RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", - hw_index, - hw_index, - dbg.wvr[hw_index], - hw_index, - dbg.wcr[hw_index]); +// if (log) log->Printf ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", +// hw_index, +// hw_index, +// dbg.wvr[hw_index], +// hw_index, +// dbg.wcr[hw_index]); kret = WriteDBG(); diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp index 30c2ea5f16d..ec3495a20d9 100644 --- a/lldb/source/lldb.cpp +++ b/lldb/source/lldb.cpp @@ -44,7 +44,6 @@ #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h" #include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h" #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" -#include "Plugins/Process/MacOSX-User/source/ProcessMacOSX.h" #include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemote.h" #include "Plugins/Platform/MacOSX/PlatformMacOSX.h" @@ -105,7 +104,6 @@ lldb_private::Initialize () ObjectFileMachO::Initialize(); ProcessKDP::Initialize(); ProcessGDBRemote::Initialize(); - //ProcessMacOSX::Initialize(); SymbolVendorMacOSX::Initialize(); PlatformMacOSX::Initialize(); PlatformRemoteiOS::Initialize(); @@ -171,7 +169,6 @@ lldb_private::Terminate () ObjectFileMachO::Terminate(); ProcessKDP::Terminate(); ProcessGDBRemote::Terminate(); - //ProcessMacOSX::Terminate(); SymbolVendorMacOSX::Terminate(); PlatformMacOSX::Terminate(); PlatformRemoteiOS::Terminate(); |

