Remove the deprecated MacOSX native plug-in.

llvm-svn: 136626
This commit is contained in:
Greg Clayton 2011-08-01 17:08:02 +00:00
parent 0516c503ec
commit 89f138ae63
37 changed files with 38 additions and 11384 deletions

View File

@ -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 */,

View File

@ -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

View File

@ -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}'");

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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__

View File

@ -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_

View File

@ -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_

View File

@ -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__)

View File

@ -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_

View File

@ -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__)

View File

@ -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_

View File

@ -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;
}

View File

@ -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_

View File

@ -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;
}

View File

@ -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_

View File

@ -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>

View File

@ -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_

View File

@ -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);
}
}

View File

@ -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_

View File

@ -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_

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
// }
// }
// }
//}
//

View File

@ -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_

View File

@ -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();

View File

@ -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();