aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/modules/LLDBConfig.cmake2
-rw-r--r--include/lldb/Core/ArchSpec.h1
-rw-r--r--include/lldb/Expression/DiagnosticManager.h2
-rw-r--r--include/lldb/Utility/StringLexer.h2
-rw-r--r--lldb.xcodeproj/project.pbxproj8
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/TestLibCxxAtomic.py4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py3
-rw-r--r--packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py145
-rw-r--r--packages/Python/lldbsuite/test/functionalities/frame_var/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/frame_var/TestFrameVar.py99
-rw-r--r--packages/Python/lldbsuite/test/functionalities/frame_var/main.c11
-rw-r--r--packages/Python/lldbsuite/test/functionalities/history/TestHistoryRecall.py45
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py6
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/TestGCore.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py2
-rw-r--r--packages/Python/lldbsuite/test/lang/c/register_variables/test.c13
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py16
-rw-r--r--source/Commands/CommandObjectCommands.cpp6
-rw-r--r--source/Commands/CommandObjectFrame.cpp90
-rw-r--r--source/Core/ArchSpec.cpp32
-rw-r--r--source/Core/Scalar.cpp2
-rw-r--r--source/Expression/DiagnosticManager.cpp9
-rw-r--r--source/Interpreter/CommandHistory.cpp4
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp69
-rw-r--r--source/Plugins/Platform/MacOSX/CMakeLists.txt1
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.cpp2
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp34
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp656
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h76
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp666
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h79
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp712
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h118
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp674
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h93
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp117
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp26
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h9
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp460
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h25
-rw-r--r--source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp71
-rw-r--r--source/Plugins/Process/NetBSD/NativeThreadNetBSD.h7
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp7
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_x86_64.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp14
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h4
-rw-r--r--source/Symbol/ClangASTContext.cpp12
-rw-r--r--source/Utility/StringLexer.cpp4
-rw-r--r--unittests/Core/ArchSpecTest.cpp19
49 files changed, 2078 insertions, 2389 deletions
diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake
index 79e82fbb3fb1..60af9504ee8a 100644
--- a/cmake/modules/LLDBConfig.cmake
+++ b/cmake/modules/LLDBConfig.cmake
@@ -433,7 +433,9 @@ endif()
find_package(Backtrace)
+include(CheckIncludeFile)
check_include_file(termios.h HAVE_TERMIOS_H)
+check_include_file(sys/event.h HAVE_SYS_EVENT_H)
# These checks exist in LLVM's configuration, so I want to match the LLVM names
# so that the check isn't duplicated, but we translate them into the LLDB names
diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h
index 648815c21371..75c7079be08d 100644
--- a/include/lldb/Core/ArchSpec.h
+++ b/include/lldb/Core/ArchSpec.h
@@ -625,6 +625,7 @@ public:
protected:
bool IsEqualTo(const ArchSpec &rhs, bool exact_match) const;
+ void UpdateCore();
llvm::Triple m_triple;
Core m_core = kCore_invalid;
diff --git a/include/lldb/Expression/DiagnosticManager.h b/include/lldb/Expression/DiagnosticManager.h
index d9024e649b80..83e67df2649a 100644
--- a/include/lldb/Expression/DiagnosticManager.h
+++ b/include/lldb/Expression/DiagnosticManager.h
@@ -128,6 +128,8 @@ public:
m_diagnostics.push_back(diagnostic);
}
+ void CopyDiagnostics(DiagnosticManager &otherDiagnostics);
+
size_t Printf(DiagnosticSeverity severity, const char *format, ...)
__attribute__((format(printf, 3, 4)));
size_t PutString(DiagnosticSeverity severity, llvm::StringRef str);
diff --git a/include/lldb/Utility/StringLexer.h b/include/lldb/Utility/StringLexer.h
index e2c31db329cc..e4fc81a85e0d 100644
--- a/include/lldb/Utility/StringLexer.h
+++ b/include/lldb/Utility/StringLexer.h
@@ -41,8 +41,6 @@ public:
bool HasAtLeast(Size s);
- bool HasAny(Character c);
-
std::string GetUnlexed();
// This will assert if there are less than s characters preceding the cursor.
diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj
index 8e44b5f07dc9..6bcd8619f0b6 100644
--- a/lldb.xcodeproj/project.pbxproj
+++ b/lldb.xcodeproj/project.pbxproj
@@ -923,6 +923,8 @@
AF33B4BE1C1FA441001B28D9 /* NetBSDSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF33B4BC1C1FA441001B28D9 /* NetBSDSignals.cpp */; };
AF33B4BF1C1FA441001B28D9 /* NetBSDSignals.h in Headers */ = {isa = PBXBuildFile; fileRef = AF33B4BD1C1FA441001B28D9 /* NetBSDSignals.h */; };
AF37E10A17C861F20061E18E /* ProcessRunLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF37E10917C861F20061E18E /* ProcessRunLock.cpp */; };
+ AF3A4AD21EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF3A4AD01EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp */; };
+ AF3A4AD31EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = AF3A4AD11EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h */; };
AF415AE71D949E4400FCE0D4 /* x86AssemblyInspectionEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF415AE51D949E4400FCE0D4 /* x86AssemblyInspectionEngine.cpp */; };
AF415AE81D949E4400FCE0D4 /* x86AssemblyInspectionEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = AF415AE61D949E4400FCE0D4 /* x86AssemblyInspectionEngine.h */; };
AF45FDE518A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF45FDE318A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp */; };
@@ -2937,6 +2939,8 @@
AF33B4BC1C1FA441001B28D9 /* NetBSDSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetBSDSignals.cpp; path = Utility/NetBSDSignals.cpp; sourceTree = "<group>"; };
AF33B4BD1C1FA441001B28D9 /* NetBSDSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetBSDSignals.h; path = Utility/NetBSDSignals.h; sourceTree = "<group>"; };
AF37E10917C861F20061E18E /* ProcessRunLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessRunLock.cpp; sourceTree = "<group>"; };
+ AF3A4AD01EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformRemoteDarwinDevice.cpp; sourceTree = "<group>"; };
+ AF3A4AD11EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRemoteDarwinDevice.h; sourceTree = "<group>"; };
AF3F54AE1B3BA59C00186E73 /* CrashReason.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrashReason.cpp; sourceTree = "<group>"; };
AF3F54AF1B3BA59C00186E73 /* CrashReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrashReason.h; sourceTree = "<group>"; };
AF3F54B21B3BA5D500186E73 /* POSIXStopInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = POSIXStopInfo.cpp; sourceTree = "<group>"; };
@@ -5426,6 +5430,8 @@
9455630D1BEAD0570073F75F /* PlatformiOSSimulatorCoreSimulatorSupport.mm */,
26C5577B132575AD008FD8FE /* PlatformMacOSX.cpp */,
26C5577C132575AD008FD8FE /* PlatformMacOSX.h */,
+ AF3A4AD01EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp */,
+ AF3A4AD11EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h */,
AF8AD6331BEC28C400150209 /* PlatformRemoteAppleTV.cpp */,
AF8AD6341BEC28C400150209 /* PlatformRemoteAppleTV.h */,
AF8AD6351BEC28C400150209 /* PlatformRemoteAppleWatch.cpp */,
@@ -6469,6 +6475,7 @@
files = (
AF8AD6381BEC28C400150209 /* PlatformRemoteAppleTV.h in Headers */,
26EFB61C1BFE8D3E00544801 /* PlatformNetBSD.h in Headers */,
+ AF3A4AD31EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h in Headers */,
AF33B4BF1C1FA441001B28D9 /* NetBSDSignals.h in Headers */,
AF6335E31C87B21E00F7D554 /* SymbolFilePDB.h in Headers */,
267F685A1CC02EBE0086832B /* RegisterInfos_s390x.h in Headers */,
@@ -7284,6 +7291,7 @@
AE6897281B94F6DE0018845D /* DWARFASTParserGo.cpp in Sources */,
945261C41B9A11FC00BF138D /* LibCxxUnorderedMap.cpp in Sources */,
26CEB5F218762056008F575A /* CommandObjectGUI.cpp in Sources */,
+ AF3A4AD21EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp in Sources */,
2689008013353E2200698AC0 /* CommandInterpreter.cpp in Sources */,
AF77E0A41A033D360096C0EA /* RegisterContextPOSIX_powerpc.cpp in Sources */,
4CDB8D6D1DBA91B6006C5B13 /* LibStdcppUniquePointer.cpp in Sources */,
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/TestLibCxxAtomic.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/TestLibCxxAtomic.py
index 2b63dbb1c83b..8d4132444fbd 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/TestLibCxxAtomic.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/atomic/TestLibCxxAtomic.py
@@ -23,8 +23,8 @@ class LibCxxAtomicTestCase(TestBase):
var.SetPreferSyntheticValue(True)
return var
- @skipIf(compiler="gcc")
- @skipIfWindows # libc++ not ported to Windows yet
+ @skipIf(compiler=["gcc"])
+ @add_test_categories(["libc++"])
def test(self):
"""Test that std::atomic as defined by libc++ is correctly printed by LLDB"""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
index dd97a9ab5977..bb20b0e7d98c 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
@@ -30,8 +30,7 @@ class LibcxxListDataFormatterTestCase(TestBase):
self.line4 = line_number('main.cpp',
'// Set fourth break point at this line.')
- @skipIf(compiler="gcc")
- @skipIfWindows # libc++ not ported to Windows yet
+ @add_test_categories(["libc++"])
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
self.build()
diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py
index be1547ea5d8f..ca8928129244 100644
--- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py
+++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py
@@ -17,55 +17,112 @@ class LibcxxSetDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- @skipIf(compiler="gcc")
- @skipIfWindows # libc++ not ported to Windows yet
+ def setUp(self):
+ TestBase.setUp(self)
+ ns = 'ndk' if lldbplatformutil.target_is_android() else ''
+ self.namespace = 'std::__' + ns + '1'
+
+ def getVariableType(self, name):
+ var = self.frame().FindVariable(name)
+ self.assertTrue(var.IsValid())
+ return var.GetType().GetCanonicalType().GetName()
+
+ @add_test_categories(["libc++"])
def test_with_run_command(self):
"""Test that that file and class static variables display correctly."""
self.build()
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
-# bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line."))
+ bkpt = self.target().FindBreakpointByID(
+ lldbutil.run_break_set_by_source_regexp(self, "Set break point at this line."))
self.runCmd("run", RUN_SUCCEEDED)
-# lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+"))
-#
-# # The stop reason of the thread should be breakpoint.
-# self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
-# substrs = ['stopped',
-# 'stop reason = breakpoint'])
-#
-# # This is the function to remove the custom formats in order to have a
-# # clean slate for the next test case.
-# def cleanup():
-# self.runCmd('type format clear', check=False)
-# self.runCmd('type summary clear', check=False)
-# self.runCmd('type filter clear', check=False)
-# self.runCmd('type synth clear', check=False)
-# self.runCmd("settings set target.max-children-count 256", check=False)
-#
-# # Execute the cleanup function during test case tear down.
-# self.addTearDownHook(cleanup)
-#
-# self.expect('image list', substrs = self.getLibcPlusPlusLibs())
-#
-# self.expect("frame variable ii",substrs = ["size=0","{}"])
-# lldbutil.continue_to_breakpoint(self.process(), bkpt)
-# self.expect("frame variable ii",substrs = ["size=6","[0] = 0","[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"])
-# lldbutil.continue_to_breakpoint(self.process(), bkpt)
-# self.expect("frame variable ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
-# self.expect("frame variable ii[2]",substrs = [" = 2"])
-# self.expect("p ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"])
-# lldbutil.continue_to_breakpoint(self.process(), bkpt)
-# self.expect("frame variable ii",substrs = ["size=0","{}"])
-# lldbutil.continue_to_breakpoint(self.process(), bkpt)
-# self.expect("frame variable ii",substrs = ["size=0","{}"])
-# self.expect("frame variable ss",substrs = ["size=0","{}"])
-# lldbutil.continue_to_breakpoint(self.process(), bkpt)
-# self.expect("frame variable ss",substrs = ["size=2",'[0] = "a"','[1] = "a very long string is right here"'])
-# lldbutil.continue_to_breakpoint(self.process(), bkpt)
-# self.expect("frame variable ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
-# self.expect("p ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"'])
-# self.expect("frame variable ss[2]",substrs = [' = "b"'])
-# lldbutil.continue_to_breakpoint(self.process(), bkpt)
-# self.expect("frame variable ss",substrs = ["size=3",'[0] = "a"','[1] = "a very long string is right here"','[2] = "c"'])
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs=['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+ self.runCmd(
+ "settings set target.max-children-count 256",
+ check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ ii_type = self.getVariableType("ii")
+ self.assertTrue(ii_type.startswith(self.namespace + "::set"),
+ "Type: " + ii_type)
+
+ self.expect("frame variable ii", substrs=["size=0", "{}"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect(
+ "frame variable ii",
+ substrs=["size=6",
+ "[0] = 0",
+ "[1] = 1",
+ "[2] = 2",
+ "[3] = 3",
+ "[4] = 4",
+ "[5] = 5"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect(
+ "frame variable ii",
+ substrs=["size=7",
+ "[2] = 2",
+ "[3] = 3",
+ "[6] = 6"])
+ self.expect("frame variable ii[2]", substrs=[" = 2"])
+ self.expect(
+ "p ii",
+ substrs=[
+ "size=7",
+ "[2] = 2",
+ "[3] = 3",
+ "[6] = 6"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii", substrs=["size=0", "{}"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect("frame variable ii", substrs=["size=0", "{}"])
+
+ ss_type = self.getVariableType("ss")
+ self.assertTrue(ii_type.startswith(self.namespace + "::set"),
+ "Type: " + ss_type)
+
+ self.expect("frame variable ss", substrs=["size=0", "{}"])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect(
+ "frame variable ss",
+ substrs=["size=2",
+ '[0] = "a"',
+ '[1] = "a very long string is right here"'])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect(
+ "frame variable ss",
+ substrs=["size=4",
+ '[2] = "b"',
+ '[3] = "c"',
+ '[0] = "a"',
+ '[1] = "a very long string is right here"'])
+ self.expect(
+ "p ss",
+ substrs=["size=4",
+ '[2] = "b"',
+ '[3] = "c"',
+ '[0] = "a"',
+ '[1] = "a very long string is right here"'])
+ self.expect("frame variable ss[2]", substrs=[' = "b"'])
+ lldbutil.continue_to_breakpoint(self.process(), bkpt)
+ self.expect(
+ "frame variable ss",
+ substrs=["size=3",
+ '[0] = "a"',
+ '[1] = "a very long string is right here"',
+ '[2] = "c"'])
diff --git a/packages/Python/lldbsuite/test/functionalities/frame_var/Makefile b/packages/Python/lldbsuite/test/functionalities/frame_var/Makefile
new file mode 100644
index 000000000000..50d4ab65a6ec
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/frame_var/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS += -std=c99
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/frame_var/TestFrameVar.py b/packages/Python/lldbsuite/test/functionalities/frame_var/TestFrameVar.py
new file mode 100644
index 000000000000..b29f94bdb059
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/frame_var/TestFrameVar.py
@@ -0,0 +1,99 @@
+"""
+Make sure the frame variable -g, -a, and -l flags work.
+"""
+
+from __future__ import print_function
+
+
+import os
+import time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+
+class TestFrameVar(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ # If your test case doesn't stress debug info, the
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ self.do_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def do_test(self):
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now create a breakpoint in main.c at the source matching
+ # "Set a breakpoint here"
+ breakpoint = target.BreakpointCreateBySourceRegex(
+ "Set a breakpoint here", lldb.SBFileSpec("main.c"))
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() >= 1,
+ VALID_BREAKPOINT)
+
+ error = lldb.SBError()
+ # This is the launch info. If you want to launch with arguments or
+ # environment variables, add them using SetArguments or
+ # SetEnvironmentEntries
+
+ launch_info = lldb.SBLaunchInfo(None)
+ process = target.Launch(launch_info, error)
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Did we hit our breakpoint?
+ from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
+ threads = get_threads_stopped_at_breakpoint(process, breakpoint)
+ self.assertTrue(
+ len(threads) == 1,
+ "There should be a thread stopped at our breakpoint")
+
+ # The hit count for the breakpoint should be 1.
+ self.assertTrue(breakpoint.GetHitCount() == 1)
+
+ frame = threads[0].GetFrameAtIndex(0)
+ command_result = lldb.SBCommandReturnObject()
+ interp = self.dbg.GetCommandInterpreter()
+
+ # Just get args:
+ result = interp.HandleCommand("frame var -l", command_result)
+ self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed")
+ output = command_result.GetOutput()
+ self.assertTrue("argc" in output, "Args didn't find argc")
+ self.assertTrue("argv" in output, "Args didn't find argv")
+ self.assertTrue("test_var" not in output, "Args found a local")
+ self.assertTrue("g_var" not in output, "Args found a global")
+
+ # Just get locals:
+ result = interp.HandleCommand("frame var -a", command_result)
+ self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed")
+ output = command_result.GetOutput()
+ self.assertTrue("argc" not in output, "Locals found argc")
+ self.assertTrue("argv" not in output, "Locals found argv")
+ self.assertTrue("test_var" in output, "Locals didn't find test_var")
+ self.assertTrue("g_var" not in output, "Locals found a global")
+
+ # Get the file statics:
+ result = interp.HandleCommand("frame var -l -a -g", command_result)
+ self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed")
+ output = command_result.GetOutput()
+ self.assertTrue("argc" not in output, "Globals found argc")
+ self.assertTrue("argv" not in output, "Globals found argv")
+ self.assertTrue("test_var" not in output, "Globals found test_var")
+ self.assertTrue("g_var" in output, "Globals didn't find g_var")
+
+
+
diff --git a/packages/Python/lldbsuite/test/functionalities/frame_var/main.c b/packages/Python/lldbsuite/test/functionalities/frame_var/main.c
new file mode 100644
index 000000000000..da23af2ac550
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/frame_var/main.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int g_var = 200;
+
+int
+main(int argc, char **argv)
+{
+ int test_var = 10;
+ printf ("Set a breakpoint here: %d %d.\n", test_var, g_var);
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/history/TestHistoryRecall.py b/packages/Python/lldbsuite/test/functionalities/history/TestHistoryRecall.py
new file mode 100644
index 000000000000..90bd64901ee5
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/history/TestHistoryRecall.py
@@ -0,0 +1,45 @@
+"""
+Make sure the !N and !-N commands work properly.
+"""
+
+from __future__ import print_function
+
+
+import os
+import time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+
+class TestHistoryRecall(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ # If your test case doesn't stress debug info, the
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_history_recall(self):
+ """Test the !N and !-N functionality of the command interpreter."""
+ self.sample_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def sample_test(self):
+ interp = self.dbg.GetCommandInterpreter()
+ result = lldb.SBCommandReturnObject()
+ interp.HandleCommand("command history", result, True)
+ interp.HandleCommand("platform list", result, True)
+
+ interp.HandleCommand("!0", result, False)
+ self.assertTrue(result.Succeeded(), "!0 command did not work: %s"%(result.GetError()))
+ self.assertTrue("command history" in result.GetOutput(), "!0 didn't rerun command history")
+
+ interp.HandleCommand("!-1", result, False)
+ self.assertTrue(result.Succeeded(), "!-1 command did not work: %s"%(result.GetError()))
+ self.assertTrue("host:" in result.GetOutput(), "!-1 didn't rerun platform list.")
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py b/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py
index 38b55ef40c6b..18c0da832606 100644
--- a/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -39,7 +39,6 @@ class LinuxCoreTestCase(TestBase):
super(LinuxCoreTestCase, self).tearDown()
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_i386(self):
"""Test that lldb can read the process information from an i386 linux core file."""
@@ -58,21 +57,18 @@ class LinuxCoreTestCase(TestBase):
self.do_test("linux-mips64el-gnuabi64", self._mips64_n64_pid, self._mips_regions)
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_x86_64(self):
"""Test that lldb can read the process information from an x86_64 linux core file."""
self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions)
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_s390x(self):
"""Test that lldb can read the process information from an s390x linux core file."""
self.do_test("linux-s390x", self._s390x_pid, self._s390x_regions)
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_same_pid_running(self):
"""Test that we read the information from the core correctly even if we have a running
@@ -102,7 +98,6 @@ class LinuxCoreTestCase(TestBase):
self.RemoveTempFile("linux-x86_64-pid.core")
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_two_cores_same_pid(self):
"""Test that we handle the situation if we have two core files with the same PID
@@ -132,7 +127,6 @@ class LinuxCoreTestCase(TestBase):
self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions)
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_FPR_SSE(self):
# check x86_64 core file
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/TestGCore.py b/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/TestGCore.py
index 5b398c1ccf0c..5a11a52e93a6 100644
--- a/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/TestGCore.py
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/TestGCore.py
@@ -23,14 +23,12 @@ class GCoreTestCase(TestBase):
_x86_64_pid = 5669
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_i386(self):
"""Test that lldb can read the process information from an i386 linux core file."""
self.do_test("linux-i386", self._i386_pid)
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_x86_64(self):
"""Test that lldb can read the process information from an x86_64 linux core file."""
diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py b/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py
index 4895c051d63e..7cc3c0775ced 100644
--- a/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py
+++ b/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py
@@ -27,14 +27,12 @@ class LinuxCoreThreadsTestCase(TestBase):
_x86_64_tid = 5250
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_i386(self):
"""Test that lldb can read the process information from an i386 linux core file."""
self.do_test("linux-i386", self._i386_pid, self._i386_tid)
@skipIf(oslist=['windows'])
- @skipIfDarwin # <rdar://problem/31380097>, fails started happening with r299199
@skipIf(triple='^mips')
def test_x86_64(self):
"""Test that lldb can read the process information from an x86_64 linux core file."""
diff --git a/packages/Python/lldbsuite/test/lang/c/register_variables/test.c b/packages/Python/lldbsuite/test/lang/c/register_variables/test.c
index 476c32899edc..b95253ef9eea 100644
--- a/packages/Python/lldbsuite/test/lang/c/register_variables/test.c
+++ b/packages/Python/lldbsuite/test/lang/c/register_variables/test.c
@@ -1,17 +1,26 @@
#include <stdio.h>
+#if defined(__arm__) || defined(__aarch64__)
+// Clang does not accept regparm attribute on these platforms.
+// Fortunately, the default calling convention passes arguments in registers
+// anyway.
+#define REGPARM(N)
+#else
+#define REGPARM(N) __attribute__((regparm(N)))
+#endif
+
struct bar {
int m1;
int m2;
};
-void f1(int a, struct bar *b) __attribute__((noinline)) __attribute__((regparm(2)));
+void f1(int a, struct bar *b) __attribute__((noinline)) REGPARM(2);
void f1(int a, struct bar *b)
{
b->m2 = b->m1 + a; // set breakpoint here
}
-void f2(struct bar *b) __attribute__((noinline)) __attribute__((regparm(1)));
+void f2(struct bar *b) __attribute__((noinline)) REGPARM(1);
void f2(struct bar *b)
{
int c = b->m2;
diff --git a/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py b/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py
index 10e29e9899dc..0100a2727b38 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py
@@ -57,16 +57,12 @@ class StaticVariableTestCase(TestBase):
startstr="(int) A::g_points[1].x = 11")
@expectedFailureAll(
- oslist=lldbplatformutil.getDarwinOSTriples(),
- bugnumber="<rdar://problem/28706946>")
- @expectedFailureAll(
- compiler=[
- "clang",
- "gcc"],
+ compiler=["gcc"],
bugnumber="Compiler emits incomplete debug info")
@expectedFailureAll(
- oslist=['freebsd'],
- bugnumber='llvm.org/pr20550 failing on FreeBSD-11')
+ compiler=["clang"],
+ compiler_version=["<", "3.8"],
+ bugnumber='llvm.org/pr20550')
@add_test_categories(['pyapi'])
def test_with_python_api(self):
"""Test Python APIs on file and class static variables."""
@@ -105,11 +101,11 @@ class StaticVariableTestCase(TestBase):
if name == 'g_points':
self.assertTrue(
val.GetValueType() == lldb.eValueTypeVariableStatic)
- self.assertTrue(val.GetNumChildren() == 2)
+ self.assertEqual(val.GetNumChildren(), 2)
elif name == 'A::g_points':
self.assertTrue(
val.GetValueType() == lldb.eValueTypeVariableGlobal)
- self.assertTrue(val.GetNumChildren() == 2)
+ self.assertEqual(val.GetNumChildren(), 2)
child1 = val.GetChildAtIndex(1)
self.DebugSBValue(child1)
child1_x = child1.GetChildAtIndex(0)
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp
index 102010e8e6f6..e39c0330b653 100644
--- a/source/Commands/CommandObjectCommands.cpp
+++ b/source/Commands/CommandObjectCommands.cpp
@@ -50,7 +50,11 @@ class CommandObjectCommandsHistory : public CommandObjectParsed {
public:
CommandObjectCommandsHistory(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "command history",
- "Dump the history of commands in this session.",
+ "Dump the history of commands in this session.\n"
+ "Commands in the history list can be run again "
+ "using \"!<INDEX>\". \"!-<OFFSET>\" will re-run "
+ "the command that is <OFFSET> commands from the end"
+ " of the list (counting the current command).",
nullptr),
m_options() {}
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index 8be9b6f9b7a6..7e81f5f94140 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -655,42 +655,62 @@ protected:
if (num_variables > 0) {
for (size_t i = 0; i < num_variables; i++) {
var_sp = variable_list->GetVariableAtIndex(i);
- bool dump_variable = true;
- std::string scope_string;
- if (dump_variable && m_option_variable.show_scope)
- scope_string = GetScopeString(var_sp).str();
-
- if (dump_variable) {
- // Use the variable object code to make sure we are
- // using the same APIs as the public API will be
- // using...
- valobj_sp = frame->GetValueObjectForFrameVariable(
- var_sp, m_varobj_options.use_dynamic);
- if (valobj_sp) {
- // When dumping all variables, don't print any variables
- // that are not in scope to avoid extra unneeded output
- if (valobj_sp->IsInScope()) {
- if (!valobj_sp->GetTargetSP()
- ->GetDisplayRuntimeSupportValues() &&
- valobj_sp->IsRuntimeSupportValue())
- continue;
-
- if (!scope_string.empty())
- s.PutCString(scope_string);
-
- if (m_option_variable.show_decl &&
- var_sp->GetDeclaration().GetFile()) {
- var_sp->GetDeclaration().DumpStopContext(&s, false);
- s.PutCString(": ");
- }
-
- options.SetFormat(format);
- options.SetVariableFormatDisplayLanguage(
- valobj_sp->GetPreferredDisplayLanguage());
- options.SetRootValueObjectName(
- var_sp ? var_sp->GetName().AsCString() : nullptr);
- valobj_sp->Dump(result.GetOutputStream(), options);
+ switch (var_sp->GetScope())
+ {
+ case eValueTypeVariableGlobal:
+ if (!m_option_variable.show_globals)
+ continue;
+ break;
+ case eValueTypeVariableStatic:
+ if (!m_option_variable.show_globals)
+ continue;
+ break;
+ case eValueTypeVariableArgument:
+ if (!m_option_variable.show_args)
+ continue;
+ break;
+ case eValueTypeVariableLocal:
+ if (!m_option_variable.show_locals)
+ continue;
+ break;
+ default:
+ continue;
+ break;
+
+ }
+ std::string scope_string;
+ if (m_option_variable.show_scope)
+ scope_string = GetScopeString(var_sp).str();
+
+ // Use the variable object code to make sure we are
+ // using the same APIs as the public API will be
+ // using...
+ valobj_sp = frame->GetValueObjectForFrameVariable(
+ var_sp, m_varobj_options.use_dynamic);
+ if (valobj_sp) {
+ // When dumping all variables, don't print any variables
+ // that are not in scope to avoid extra unneeded output
+ if (valobj_sp->IsInScope()) {
+ if (!valobj_sp->GetTargetSP()
+ ->GetDisplayRuntimeSupportValues() &&
+ valobj_sp->IsRuntimeSupportValue())
+ continue;
+
+ if (!scope_string.empty())
+ s.PutCString(scope_string);
+
+ if (m_option_variable.show_decl &&
+ var_sp->GetDeclaration().GetFile()) {
+ var_sp->GetDeclaration().DumpStopContext(&s, false);
+ s.PutCString(": ");
}
+
+ options.SetFormat(format);
+ options.SetVariableFormatDisplayLanguage(
+ valobj_sp->GetPreferredDisplayLanguage());
+ options.SetRootValueObjectName(
+ var_sp ? var_sp->GetName().AsCString() : nullptr);
+ valobj_sp->Dump(result.GetOutputStream(), options);
}
}
}
diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp
index 60ee237aa0f5..7c1b399177fd 100644
--- a/source/Core/ArchSpec.cpp
+++ b/source/Core/ArchSpec.cpp
@@ -834,19 +834,7 @@ lldb::ByteOrder ArchSpec::GetByteOrder() const {
bool ArchSpec::SetTriple(const llvm::Triple &triple) {
m_triple = triple;
-
- llvm::StringRef arch_name(m_triple.getArchName());
- const CoreDefinition *core_def = FindCoreDefinition(arch_name);
- if (core_def) {
- m_core = core_def->core;
- // Set the byte order to the default byte order for an architecture.
- // This can be modified if needed for cases when cores handle both
- // big and little endian
- m_byte_order = core_def->default_byte_order;
- } else {
- Clear();
- }
-
+ UpdateCore();
return IsValid();
}
@@ -994,8 +982,10 @@ void ArchSpec::MergeFrom(const ArchSpec &other) {
GetTriple().setVendor(other.GetTriple().getVendor());
if (TripleOSIsUnspecifiedUnknown() && !other.TripleOSIsUnspecifiedUnknown())
GetTriple().setOS(other.GetTriple().getOS());
- if (GetTriple().getArch() == llvm::Triple::UnknownArch)
+ if (GetTriple().getArch() == llvm::Triple::UnknownArch) {
GetTriple().setArch(other.GetTriple().getArch());
+ UpdateCore();
+ }
if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
!TripleVendorWasSpecified()) {
if (other.TripleVendorWasSpecified())
@@ -1190,6 +1180,20 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
return false;
}
+void ArchSpec::UpdateCore() {
+ llvm::StringRef arch_name(m_triple.getArchName());
+ const CoreDefinition *core_def = FindCoreDefinition(arch_name);
+ if (core_def) {
+ m_core = core_def->core;
+ // Set the byte order to the default byte order for an architecture.
+ // This can be modified if needed for cases when cores handle both
+ // big and little endian
+ m_byte_order = core_def->default_byte_order;
+ } else {
+ Clear();
+ }
+}
+
//===----------------------------------------------------------------------===//
// Helper methods.
diff --git a/source/Core/Scalar.cpp b/source/Core/Scalar.cpp
index 88ad430ddbae..3adf85098648 100644
--- a/source/Core/Scalar.cpp
+++ b/source/Core/Scalar.cpp
@@ -2745,7 +2745,7 @@ bool Scalar::SignExtend(uint32_t sign_bit_pos) {
if (max_bit_pos == sign_bit_pos)
return true;
else if (sign_bit_pos < (max_bit_pos - 1)) {
- llvm::APInt sign_bit = llvm::APInt::getSignBit(sign_bit_pos + 1);
+ llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1);
llvm::APInt bitwize_and = m_integer & sign_bit;
if (bitwize_and.getBoolValue()) {
const llvm::APInt mask =
diff --git a/source/Expression/DiagnosticManager.cpp b/source/Expression/DiagnosticManager.cpp
index 5ade0817b1e2..ae20feb910dd 100644
--- a/source/Expression/DiagnosticManager.cpp
+++ b/source/Expression/DiagnosticManager.cpp
@@ -79,3 +79,12 @@ size_t DiagnosticManager::PutString(DiagnosticSeverity severity,
AddDiagnostic(str, severity, eDiagnosticOriginLLDB);
return str.size();
}
+
+void DiagnosticManager::CopyDiagnostics(DiagnosticManager &otherDiagnostics) {
+ for (const DiagnosticList::value_type &other_diagnostic:
+ otherDiagnostics.Diagnostics()) {
+ AddDiagnostic(
+ other_diagnostic->GetMessage(), other_diagnostic->GetSeverity(),
+ other_diagnostic->getKind(), other_diagnostic->GetCompilerID());
+ }
+}
diff --git a/source/Interpreter/CommandHistory.cpp b/source/Interpreter/CommandHistory.cpp
index 0fa25ed806ff..ca5c90692b6a 100644
--- a/source/Interpreter/CommandHistory.cpp
+++ b/source/Interpreter/CommandHistory.cpp
@@ -47,13 +47,13 @@ CommandHistory::FindString(llvm::StringRef input_str) const {
size_t idx = 0;
if (input_str.front() == '-') {
- if (input_str.drop_front(2).getAsInteger(0, idx))
+ if (input_str.drop_front(1).getAsInteger(0, idx))
return llvm::None;
if (idx >= m_history.size())
return llvm::None;
idx = m_history.size() - idx;
} else {
- if (input_str.drop_front().getAsInteger(0, idx))
+ if (input_str.getAsInteger(0, idx))
return llvm::None;
if (idx >= m_history.size())
return llvm::None;
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index 638112b9ebde..7a9e66cf5481 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -1810,6 +1810,7 @@ enum ExpressionStrings {
const int jit_max_expr_size = 512;
// Retrieve the string to JIT for the given expression
+#define JIT_TEMPLATE_CONTEXT "void* ctxt = (void*)rsDebugGetContextWrapper(0x%" PRIx64 "); "
const char *JITTemplate(ExpressionStrings e) {
// Format strings containing the expressions we may need to evaluate.
static std::array<const char *, _eExprLast> runtime_expressions = {
@@ -1817,57 +1818,65 @@ const char *JITTemplate(ExpressionStrings e) {
"(int*)_"
"Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocation"
"CubemapFace"
- "(0x%" PRIx64 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", 0, 0)",
+ "(0x%" PRIx64 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", 0, 0)", // eExprGetOffsetPtr
// Type* rsaAllocationGetType(Context*, Allocation*)
- "(void*)rsaAllocationGetType(0x%" PRIx64 ", 0x%" PRIx64 ")",
+ JIT_TEMPLATE_CONTEXT "(void*)rsaAllocationGetType(ctxt, 0x%" PRIx64 ")", // eExprAllocGetType
// rsaTypeGetNativeData(Context*, Type*, void* typeData, size) Pack the
// data in the following way mHal.state.dimX; mHal.state.dimY;
// mHal.state.dimZ; mHal.state.lodCount; mHal.state.faces; mElement; into
// typeData Need to specify 32 or 64 bit for uint_t since this differs
// between devices
- "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64
- ", 0x%" PRIx64 ", data, 6); data[0]", // X dim
- "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64
- ", 0x%" PRIx64 ", data, 6); data[1]", // Y dim
- "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64
- ", 0x%" PRIx64 ", data, 6); data[2]", // Z dim
- "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64
- ", 0x%" PRIx64 ", data, 6); data[5]", // Element ptr
+ JIT_TEMPLATE_CONTEXT
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
+ ", 0x%" PRIx64 ", data, 6); data[0]", // eExprTypeDimX
+ JIT_TEMPLATE_CONTEXT
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
+ ", 0x%" PRIx64 ", data, 6); data[1]", // eExprTypeDimY
+ JIT_TEMPLATE_CONTEXT
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
+ ", 0x%" PRIx64 ", data, 6); data[2]", // eExprTypeDimZ
+ JIT_TEMPLATE_CONTEXT
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
+ ", 0x%" PRIx64 ", data, 6); data[5]", // eExprTypeElemPtr
// rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
// Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into
// elemData
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64
- ", 0x%" PRIx64 ", data, 5); data[0]", // Type
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64
- ", 0x%" PRIx64 ", data, 5); data[1]", // Kind
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64
- ", 0x%" PRIx64 ", data, 5); data[3]", // Vector Size
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64
- ", 0x%" PRIx64 ", data, 5); data[4]", // Field Count
+ JIT_TEMPLATE_CONTEXT
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
+ ", 0x%" PRIx64 ", data, 5); data[0]", // eExprElementType
+ JIT_TEMPLATE_CONTEXT
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
+ ", 0x%" PRIx64 ", data, 5); data[1]", // eExprElementKind
+ JIT_TEMPLATE_CONTEXT
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
+ ", 0x%" PRIx64 ", data, 5); data[3]", // eExprElementVec
+ JIT_TEMPLATE_CONTEXT
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
+ ", 0x%" PRIx64 ", data, 5); data[4]", // eExprElementFieldCount
// rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t
// *ids, const char **names, size_t *arraySizes, uint32_t dataSize)
// Needed for Allocations of structs to gather details about
// fields/Subelements Element* of field
- "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
+ JIT_TEMPLATE_CONTEXT "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
"]; size_t arr_size[%" PRIu32 "];"
- "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64
- ", ids, names, arr_size, %" PRIu32 "); ids[%" PRIu32 "]",
+ "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64
+ ", ids, names, arr_size, %" PRIu32 "); ids[%" PRIu32 "]", // eExprSubelementsId
// Name of field
- "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
+ JIT_TEMPLATE_CONTEXT "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
"]; size_t arr_size[%" PRIu32 "];"
- "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64
- ", ids, names, arr_size, %" PRIu32 "); names[%" PRIu32 "]",
+ "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64
+ ", ids, names, arr_size, %" PRIu32 "); names[%" PRIu32 "]", // eExprSubelementsName
// Array size of field
- "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
+ JIT_TEMPLATE_CONTEXT "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
"]; size_t arr_size[%" PRIu32 "];"
- "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64
- ", ids, names, arr_size, %" PRIu32 "); arr_size[%" PRIu32 "]"}};
+ "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64
+ ", ids, names, arr_size, %" PRIu32 "); arr_size[%" PRIu32 "]"}}; // eExprSubelementsArrSize
return runtime_expressions[e];
}
@@ -1979,8 +1988,8 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
for (uint32_t i = 0; i < num_exprs; ++i) {
const char *fmt_str = JITTemplate(ExpressionStrings(eExprTypeDimX + i));
- int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, bits,
- *alloc->context.get(), *alloc->type_ptr.get());
+ int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str,
+ *alloc->context.get(), bits, *alloc->type_ptr.get());
if (written < 0) {
if (log)
log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
@@ -2105,7 +2114,7 @@ bool RenderScriptRuntime::JITSubelements(Element &elem,
const char *fmt_str =
JITTemplate(ExpressionStrings(eExprSubelementsId + expr_index));
int written = snprintf(expr_buffer, jit_max_expr_size, fmt_str,
- field_count, field_count, field_count, context,
+ context, field_count, field_count, field_count,
*elem.element_ptr.get(), field_count, field_index);
if (written < 0) {
if (log)
diff --git a/source/Plugins/Platform/MacOSX/CMakeLists.txt b/source/Plugins/Platform/MacOSX/CMakeLists.txt
index 449db7cd0612..f8d911b321f8 100644
--- a/source/Plugins/Platform/MacOSX/CMakeLists.txt
+++ b/source/Plugins/Platform/MacOSX/CMakeLists.txt
@@ -5,6 +5,7 @@ list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES
PlatformRemoteiOS.cpp
PlatformRemoteAppleTV.cpp
PlatformRemoteAppleWatch.cpp
+ PlatformRemoteDarwinDevice.cpp
)
list(APPEND PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 7c90f87189a7..02459045869a 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -569,6 +569,8 @@ bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx,
#define OSNAME "tvos"
#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
#define OSNAME "watchos"
+#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
+#define OSNAME "bridgeos"
#else
#define OSNAME "ios"
#endif
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index 7116dca65911..08df0565acc8 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -508,9 +508,10 @@ PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
ConstString file_spec_extension = file_spec.GetFileNameExtension();
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("PlatformDarwinKernel examining %s",
- file_spec.GetPath().c_str());
+ Log *log_verbose(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM | LLDB_LOG_OPTION_VERBOSE));
+
+ if (log_verbose)
+ log_verbose->Printf ("PlatformDarwinKernel examining '%s'", file_spec.GetPath().c_str());
PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton;
if (ft == llvm::sys::fs::file_type::regular_file ||
@@ -520,9 +521,21 @@ PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
strncmp(filename.GetCString(), "mach", 4) == 0) &&
file_spec_extension != g_dsym_suffix) {
if (KernelHasdSYMSibling(file_spec))
+ {
+ if (log)
+ {
+ log->Printf ("PlatformDarwinKernel registering kernel binary '%s' with dSYM sibling", file_spec.GetPath().c_str());
+ }
thisp->m_kernel_binaries_with_dsyms.push_back(file_spec);
+ }
else
+ {
+ if (log)
+ {
+ log->Printf ("PlatformDarwinKernel registering kernel binary '%s', no dSYM", file_spec.GetPath().c_str());
+ }
thisp->m_kernel_binaries_without_dsyms.push_back(file_spec);
+ }
return FileSpec::eEnumerateDirectoryResultNext;
}
} else if (ft == llvm::sys::fs::file_type::directory_file &&
@@ -556,6 +569,8 @@ PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
if (recurse && file_spec_extension != g_dsym_suffix &&
file_spec_extension != g_kext_suffix &&
file_spec_extension != g_bundle_suffix) {
+ if (log_verbose)
+ log_verbose->Printf ("PlatformDarwinKernel descending into directory '%s'", file_spec.GetPath().c_str());
return FileSpec::eEnumerateDirectoryResultEnter;
} else {
return FileSpec::eEnumerateDirectoryResultNext;
@@ -564,6 +579,7 @@ PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
void PlatformDarwinKernel::AddKextToMap(PlatformDarwinKernel *thisp,
const FileSpec &file_spec) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
CFCBundle bundle(file_spec.GetPath().c_str());
CFStringRef bundle_id(bundle.GetIdentifier());
if (bundle_id && CFGetTypeID(bundle_id) == CFStringGetTypeID()) {
@@ -572,11 +588,23 @@ void PlatformDarwinKernel::AddKextToMap(PlatformDarwinKernel *thisp,
kCFStringEncodingUTF8)) {
ConstString bundle_conststr(bundle_id_buf);
if (KextHasdSYMSibling(file_spec))
+ {
+ if (log)
+ {
+ log->Printf ("PlatformDarwinKernel registering kext binary '%s' with dSYM sibling", file_spec.GetPath().c_str());
+ }
thisp->m_name_to_kext_path_map_with_dsyms.insert(
std::pair<ConstString, FileSpec>(bundle_conststr, file_spec));
+ }
else
+ {
+ if (log)
+ {
+ log->Printf ("PlatformDarwinKernel registering kext binary '%s', no dSYM", file_spec.GetPath().c_str());
+ }
thisp->m_name_to_kext_path_map_without_dsyms.insert(
std::pair<ConstString, FileSpec>(bundle_conststr, file_spec));
+ }
}
}
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
index 05d1bd49dafe..6fdaa5997b46 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
@@ -37,22 +37,7 @@ using namespace lldb_private;
/// Default Constructor
//------------------------------------------------------------------
PlatformRemoteAppleTV::PlatformRemoteAppleTV()
- : PlatformDarwin(false), // This is a remote platform
- m_sdk_directory_infos(), m_device_support_directory(),
- m_device_support_directory_for_os_version(), m_build_update(),
- m_last_module_sdk_idx(UINT32_MAX),
- m_connected_module_sdk_idx(UINT32_MAX) {}
-
-PlatformRemoteAppleTV::SDKDirectoryInfo::SDKDirectoryInfo(
- const lldb_private::FileSpec &sdk_dir)
- : directory(sdk_dir), build(), version_major(0), version_minor(0),
- version_update(0), user_cached(false) {
- llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
- llvm::StringRef build_str;
- std::tie(version_major, version_minor, version_update, build_str) =
- ParseVersionBuildDir(dirname_str);
- build.SetString(build_str);
-}
+ : PlatformRemoteDarwinDevice () {}
//------------------------------------------------------------------
// Static Variables
@@ -165,615 +150,6 @@ const char *PlatformRemoteAppleTV::GetDescriptionStatic() {
return "Remote Apple TV platform plug-in.";
}
-void PlatformRemoteAppleTV::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
- const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
- if (sdk_directory)
- strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString(" SDK Path: error: unable to locate SDK\n");
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
- sdk_dir_info.directory.GetPath().c_str());
- }
-}
-
-Error PlatformRemoteAppleTV::ResolveExecutable(
- const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(ms);
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one
- // ourselves
- Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists()) {
- if (resolved_module_spec.GetArchitecture().IsValid() ||
- resolved_module_spec.GetUUID().IsValid()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- nullptr, nullptr, nullptr);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- nullptr, nullptr, nullptr);
- // Did we find an executable using one of the
- if (error.Success()) {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(), arch_names.GetData());
- } else {
- error.SetErrorStringWithFormat(
- "'%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- } else {
- error.SetErrorStringWithFormat(
- "'%s' does not exist",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
-
- return error;
-}
-
-FileSpec::EnumerateDirectoryResult
-PlatformRemoteAppleTV::GetContainedFilesIntoVectorOfStringsCallback(
- void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
- ((PlatformRemoteAppleTV::SDKDirectoryInfoCollection *)baton)
- ->push_back(PlatformRemoteAppleTV::SDKDirectoryInfo(file_spec));
- return FileSpec::eEnumerateDirectoryResultNext;
-}
-
-bool PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded() {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
- if (m_sdk_directory_infos.empty()) {
- const char *device_support_dir = GetDeviceSupportDirectory();
- if (log) {
- log->Printf("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded Got "
- "DeviceSupport directory %s",
- device_support_dir);
- }
- if (device_support_dir) {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
-
- SDKDirectoryInfoCollection builtin_sdk_directory_infos;
- FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
- find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &builtin_sdk_directory_infos);
-
- // Only add SDK directories that have symbols in them, some SDKs only
- // contain
- // developer disk images and no symbols, so they aren't useful to us.
- FileSpec sdk_symbols_symlink_fspec;
- for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
- sdk_symbols_symlink_fspec = sdk_directory_info.directory;
- sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal");
- if (sdk_symbols_symlink_fspec.Exists()) {
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log) {
- log->Printf("PlatformRemoteAppleTV::"
- "UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
- "directory %s",
- sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- } else {
- sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
- if (sdk_symbols_symlink_fspec.Exists())
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log) {
- log->Printf("PlatformRemoteAppleTV::"
- "UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
- "directory %s",
- sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- }
-
- const uint32_t num_installed = m_sdk_directory_infos.size();
- FileSpec local_sdk_cache("~/Library/Developer/Xcode/tvOS DeviceSupport",
- true);
- if (!local_sdk_cache.Exists()) {
- // Try looking for another possible name
- local_sdk_cache = FileSpec(
- "~/Library/Developer/Xcode/Apple TVOS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists()) {
- // Try looking for another possible name
- local_sdk_cache =
- FileSpec("~/Library/Developer/Xcode/AppleTVOS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists()) {
- // Try looking for another possible name
- local_sdk_cache = FileSpec(
- "~/Library/Developer/Xcode/AppleTV OS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists()) {
- // Try looking for another possible name
- local_sdk_cache = FileSpec(
- "~/Library/Developer/Xcode/Apple TV OS DeviceSupport", true);
- }
- if (local_sdk_cache.Exists()) {
- if (log) {
- log->Printf("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded "
- "searching %s for additional SDKs",
- local_sdk_cache.GetPath().c_str());
- }
- char path[PATH_MAX];
- if (local_sdk_cache.GetPath(path, sizeof(path))) {
- FileSpec::EnumerateDirectory(
- path, find_directories, find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &m_sdk_directory_infos);
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
- m_sdk_directory_infos[i].user_cached = true;
- if (log) {
- log->Printf("PlatformRemoteAppleTV::"
- "UpdateSDKDirectoryInfosIfNeeded user SDK directory "
- "%s",
- m_sdk_directory_infos[i].directory.GetPath().c_str());
- }
- }
- }
- }
- }
- }
- return !m_sdk_directory_infos.empty();
-}
-
-const PlatformRemoteAppleTV::SDKDirectoryInfo *
-PlatformRemoteAppleTV::GetSDKDirectoryForCurrentOSVersion() {
- uint32_t i;
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
-
- // Check to see if the user specified a build string. If they did, then
- // be sure to match it.
- std::vector<bool> check_sdk_info(num_sdk_infos, true);
- ConstString build(m_sdk_build);
- if (build) {
- for (i = 0; i < num_sdk_infos; ++i)
- check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
- }
-
- // If we are connected we can find the version of the OS the platform
- // us running on and select the right SDK
- uint32_t major, minor, update;
- if (GetOSVersion(major, minor, update)) {
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- // First try for an exact match of major, minor and update
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor &&
- m_sdk_directory_infos[i].version_update == update) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // First try for an exact match of major and minor
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // Lastly try to match of major version only..
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- }
- } else if (build) {
- // No version, just a build number, search for the first one that matches
- for (i = 0; i < num_sdk_infos; ++i)
- if (check_sdk_info[i])
- return &m_sdk_directory_infos[i];
- }
- }
- return nullptr;
-}
-
-const PlatformRemoteAppleTV::SDKDirectoryInfo *
-PlatformRemoteAppleTV::GetSDKDirectoryForLatestOSVersion() {
- const PlatformRemoteAppleTV::SDKDirectoryInfo *result = nullptr;
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (sdk_dir_info.version_major != UINT32_MAX) {
- if (result == nullptr ||
- sdk_dir_info.version_major > result->version_major) {
- result = &sdk_dir_info;
- } else if (sdk_dir_info.version_major == result->version_major) {
- if (sdk_dir_info.version_minor > result->version_minor) {
- result = &sdk_dir_info;
- } else if (sdk_dir_info.version_minor == result->version_minor) {
- if (sdk_dir_info.version_update > result->version_update) {
- result = &sdk_dir_info;
- }
- }
- }
- }
- }
- }
- return result;
-}
-
-const char *PlatformRemoteAppleTV::GetDeviceSupportDirectory() {
- if (m_device_support_directory.empty()) {
- const char *device_support_dir = GetDeveloperDirectory();
- if (device_support_dir) {
- m_device_support_directory.assign(device_support_dir);
- m_device_support_directory.append(
- "/Platforms/AppleTVOS.platform/DeviceSupport");
- } else {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory.assign(1, '\0');
- }
- }
- // We should have put a single NULL character into m_device_support_directory
- // or it should have a valid path if the code gets here
- assert(m_device_support_directory.empty() == false);
- if (m_device_support_directory[0])
- return m_device_support_directory.c_str();
- return nullptr;
-}
-
-const char *PlatformRemoteAppleTV::GetDeviceSupportDirectoryForOSVersion() {
- if (m_sdk_sysroot)
- return m_sdk_sysroot.GetCString();
-
- if (m_device_support_directory_for_os_version.empty()) {
- const PlatformRemoteAppleTV::SDKDirectoryInfo *sdk_dir_info =
- GetSDKDirectoryForCurrentOSVersion();
- if (sdk_dir_info == nullptr)
- sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
- if (sdk_dir_info) {
- char path[PATH_MAX];
- if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
- m_device_support_directory_for_os_version = path;
- return m_device_support_directory_for_os_version.c_str();
- }
- } else {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory_for_os_version.assign(1, '\0');
- }
- }
- // We should have put a single NULL character into
- // m_device_support_directory_for_os_version
- // or it should have a valid path if the code gets here
- assert(m_device_support_directory_for_os_version.empty() == false);
- if (m_device_support_directory_for_os_version[0])
- return m_device_support_directory_for_os_version.c_str();
- return nullptr;
-}
-
-uint32_t
-PlatformRemoteAppleTV::FindFileInAllSDKs(const char *platform_file_path,
- FileSpecList &file_list) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (platform_file_path && platform_file_path[0] &&
- UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- lldb_private::FileSpec local_file;
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
- m_sdk_directory_infos[sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
- file_list.Append(local_file);
- }
- }
- }
- return file_list.GetSize();
-}
-
-bool PlatformRemoteAppleTV::GetFileInSDK(const char *platform_file_path,
- uint32_t sdk_idx,
- lldb_private::FileSpec &local_file) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (sdk_idx < m_sdk_directory_infos.size()) {
- std::string sdkroot_path =
- m_sdk_directory_infos[sdk_idx].directory.GetPath();
- if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
- // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
- // the
- // SDK root directory and the file path.
-
- const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
- for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
- local_file.SetFile(sdkroot_path, false);
- if (paths_to_try[i][0] != '\0')
- local_file.AppendPathComponent(paths_to_try[i]);
- local_file.AppendPathComponent(platform_file_path);
- local_file.ResolvePath();
- if (local_file.Exists()) {
- if (log)
- log->Printf("Found a copy of %s in the SDK dir %s/%s",
- platform_file_path, sdkroot_path.c_str(),
- paths_to_try[i]);
- return true;
- }
- local_file.Clear();
- }
- }
- }
- return false;
-}
-
-Error PlatformRemoteAppleTV::GetSymbolFile(const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- Error error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- char resolved_path[PATH_MAX];
-
- const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
- if (os_version_dir) {
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists()) {
- if (log) {
- log->Printf("Found a copy of %s in the DeviceSupport dir %s",
- platform_file_path, os_version_dir);
- }
- return error;
- }
-
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
- os_version_dir, platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists()) {
- if (log) {
- log->Printf(
- "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
- platform_file_path, os_version_dir);
- }
- return error;
- }
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
- os_version_dir, platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists()) {
- if (log) {
- log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
- platform_file_path, os_version_dir);
- }
- return error;
- }
- }
- local_file = platform_file;
- if (local_file.Exists())
- return error;
-
- error.SetErrorStringWithFormat(
- "unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path, GetPluginName().GetCString());
- } else {
- error.SetErrorString("invalid platform file argument");
- }
- return error;
-}
-
-Error PlatformRemoteAppleTV::GetSharedModule(
- const ModuleSpec &module_spec, lldb_private::Process *process,
- ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
- // For Apple TV, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
- const FileSpec &platform_file = module_spec.GetFileSpec();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
-
- Error error;
- char platform_file_path[PATH_MAX];
-
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- ModuleSpec platform_module_spec(module_spec);
-
- UpdateSDKDirectoryInfosIfNeeded();
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
-
- // If we are connected we migth be able to correctly deduce the SDK
- // directory
- // using the OS build.
- const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
- if (connected_sdk_idx < num_sdk_infos) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[connected_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, connected_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
- if (module_sp) {
- m_last_module_sdk_idx = connected_sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
-
- // Try the last SDK index if it is set as most files from an SDK
- // will tend to be valid in that same SDK.
- if (m_last_module_sdk_idx < num_sdk_infos) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
- m_sdk_directory_infos[m_last_module_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
- if (module_sp) {
- error.Clear();
- return error;
- }
- }
- }
-
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
- if (m_last_module_sdk_idx == sdk_idx) {
- // Skip the last module SDK index if we already searched
- // it above
- continue;
- }
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
- m_sdk_directory_infos[sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, sdk_idx,
- platform_module_spec.GetFileSpec())) {
- // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
-
- error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
- if (module_sp) {
- // Remember the index of the last SDK that we found a file
- // in in case the wrong SDK was selected.
- m_last_module_sdk_idx = sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
- }
- // Not the module we are looking for... Nothing to see here...
- module_sp.reset();
-
- // This may not be an SDK-related module. Try whether we can bring in the
- // thing to our local cache.
- error = GetSharedModuleWithLocalCache(module_spec, module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
- if (error.Success())
- return error;
-
- // See if the file is present in any of the module_search_paths_ptr
- // directories.
- if (!module_sp && module_search_paths_ptr && platform_file) {
- // create a vector of all the file / directory names in platform_file
- // e.g. this might be
- // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
- //
- // We'll need to look in the module_search_paths_ptr directories for
- // both "UIFoundation" and "UIFoundation.framework" -- most likely the
- // latter will be the one we find there.
-
- FileSpec platform_pull_apart(platform_file);
- std::vector<std::string> path_parts;
- ConstString unix_root_dir("/");
- while (true) {
- ConstString part = platform_pull_apart.GetLastPathComponent();
- platform_pull_apart.RemoveLastPathComponent();
- if (part.IsEmpty() || part == unix_root_dir)
- break;
- path_parts.push_back(part.AsCString());
- }
- const size_t path_parts_size = path_parts.size();
-
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i = 0; i < num_module_search_paths; ++i) {
- // Create a new FileSpec with this module_search_paths_ptr
- // plus just the filename ("UIFoundation"), then the parent
- // dir plus filename ("UIFoundation.framework/UIFoundation")
- // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
-
- for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
- FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
-
- // Add the components backwards. For
- // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
- // path_parts is
- // [0] UIFoundation
- // [1] UIFoundation.framework
- // [2] PrivateFrameworks
- //
- // and if 'j' is 2, we want to append path_parts[1] and then
- // path_parts[0], aka
- // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
- // path.
-
- for (int k = j; k >= 0; --k) {
- path_to_try.AppendPathComponent(path_parts[k]);
- }
-
- if (path_to_try.Exists()) {
- ModuleSpec new_module_spec(module_spec);
- new_module_spec.GetFileSpec() = path_to_try;
- Error new_error(Platform::GetSharedModule(
- new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp) {
- module_sp->SetPlatformFileSpec(path_to_try);
- return new_error;
- }
- }
- }
- }
- }
-
- const bool always_create = false;
- error = ModuleList::GetSharedModule(
- module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
- did_create_ptr, always_create);
-
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
-}
-
bool PlatformRemoteAppleTV::GetSupportedArchitectureAtIndex(uint32_t idx,
ArchSpec &arch) {
ArchSpec system_arch(GetSystemArchitecture());
@@ -860,23 +236,15 @@ bool PlatformRemoteAppleTV::GetSupportedArchitectureAtIndex(uint32_t idx,
return false;
}
-uint32_t PlatformRemoteAppleTV::GetConnectedSDKIndex() {
- if (IsConnected()) {
- if (m_connected_module_sdk_idx == UINT32_MAX) {
- std::string build;
- if (GetRemoteOSBuildString(build)) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
- build.c_str())) {
- m_connected_module_sdk_idx = i;
- }
- }
- }
- }
- } else {
- m_connected_module_sdk_idx = UINT32_MAX;
- }
- return m_connected_module_sdk_idx;
+
+void PlatformRemoteAppleTV::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
+{
+ dirnames.clear();
+ dirnames.push_back("tvOS DeviceSupport");
}
+
+std::string PlatformRemoteAppleTV::GetPlatformName ()
+{
+ return "AppleTVOS.platform";
+}
+
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
index beae827edba4..08dd231e85ee 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
@@ -20,9 +20,9 @@
#include "llvm/Support/FileSystem.h"
-#include "PlatformDarwin.h"
+#include "PlatformRemoteDarwinDevice.h"
-class PlatformRemoteAppleTV : public PlatformDarwin {
+class PlatformRemoteAppleTV : public PlatformRemoteDarwinDevice {
public:
PlatformRemoteAppleTV();
@@ -43,9 +43,6 @@ public:
static const char *GetDescriptionStatic();
//------------------------------------------------------------
- // Class Methods
- //------------------------------------------------------------
- //------------------------------------------------------------
// lldb_private::PluginInterface functions
//------------------------------------------------------------
lldb_private::ConstString GetPluginName() override {
@@ -57,80 +54,21 @@ public:
//------------------------------------------------------------
// lldb_private::Platform functions
//------------------------------------------------------------
- lldb_private::Error ResolveExecutable(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
const char *GetDescription() override { return GetDescriptionStatic(); }
- void GetStatus(lldb_private::Stream &strm) override;
-
- virtual lldb_private::Error
- GetSymbolFile(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
bool GetSupportedArchitectureAtIndex(uint32_t idx,
lldb_private::ArchSpec &arch) override;
- void
- AddClangModuleCompilationOptions(lldb_private::Target *target,
- std::vector<std::string> &options) override {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
- target, options, PlatformDarwin::SDKType::iPhoneOS);
- }
-
protected:
- struct SDKDirectoryInfo {
- SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
- lldb_private::FileSpec directory;
- lldb_private::ConstString build;
- uint32_t version_major;
- uint32_t version_minor;
- uint32_t version_update;
- bool user_cached;
- };
- typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
- std::mutex m_sdk_dir_mutex;
- SDKDirectoryInfoCollection m_sdk_directory_infos;
- std::string m_device_support_directory;
- std::string m_device_support_directory_for_os_version;
- std::string m_build_update;
- uint32_t m_last_module_sdk_idx;
- uint32_t m_connected_module_sdk_idx;
-
- bool UpdateSDKDirectoryInfosIfNeeded();
- const char *GetDeviceSupportDirectory();
-
- const char *GetDeviceSupportDirectoryForOSVersion();
-
- const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
-
- const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
-
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetContainedFilesIntoVectorOfStringsCallback(
- void *baton, llvm::sys::fs::file_type ft,
- const lldb_private::FileSpec &file_spec);
-
- uint32_t FindFileInAllSDKs(const char *platform_file_path,
- lldb_private::FileSpecList &file_list);
-
- bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
- lldb_private::FileSpec &local_file);
+ //------------------------------------------------------------
+ // lldb_private::PlatformRemoteDarwinDevice functions
+ //------------------------------------------------------------
- uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
- lldb_private::FileSpecList &file_list);
+ void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
- uint32_t GetConnectedSDKIndex();
+ std::string GetPlatformName () override;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleTV);
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
index 139364a82b98..186926430973 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
@@ -34,27 +34,6 @@ using namespace lldb;
using namespace lldb_private;
//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformRemoteAppleWatch::PlatformRemoteAppleWatch()
- : PlatformDarwin(false), // This is a remote platform
- m_sdk_directory_infos(), m_device_support_directory(),
- m_device_support_directory_for_os_version(), m_build_update(),
- m_last_module_sdk_idx(UINT32_MAX),
- m_connected_module_sdk_idx(UINT32_MAX) {}
-
-PlatformRemoteAppleWatch::SDKDirectoryInfo::SDKDirectoryInfo(
- const lldb_private::FileSpec &sdk_dir)
- : directory(sdk_dir), build(), version_major(0), version_minor(0),
- version_update(0), user_cached(false) {
- llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
- llvm::StringRef build_str;
- std::tie(version_major, version_minor, version_update, build_str) =
- ParseVersionBuildDir(dirname_str);
- build.SetString(build_str);
-}
-
-//------------------------------------------------------------------
// Static Variables
//------------------------------------------------------------------
static uint32_t g_initialize_count = 0;
@@ -175,618 +154,11 @@ const char *PlatformRemoteAppleWatch::GetDescriptionStatic() {
return "Remote Apple Watch platform plug-in.";
}
-void PlatformRemoteAppleWatch::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
- const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
- if (sdk_directory)
- strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString(" SDK Path: error: unable to locate SDK\n");
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
- sdk_dir_info.directory.GetPath().c_str());
- }
-}
-
-Error PlatformRemoteAppleWatch::ResolveExecutable(
- const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(ms);
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one
- // ourselves
- Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists()) {
- if (resolved_module_spec.GetArchitecture().IsValid() ||
- resolved_module_spec.GetUUID().IsValid()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- nullptr, nullptr, nullptr);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- nullptr, nullptr, nullptr);
- // Did we find an executable using one of the
- if (error.Success()) {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(), arch_names.GetData());
- } else {
- error.SetErrorStringWithFormat(
- "'%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- } else {
- error.SetErrorStringWithFormat(
- "'%s' does not exist",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
-
- return error;
-}
-
-FileSpec::EnumerateDirectoryResult
-PlatformRemoteAppleWatch::GetContainedFilesIntoVectorOfStringsCallback(
- void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
- ((PlatformRemoteAppleWatch::SDKDirectoryInfoCollection *)baton)
- ->push_back(PlatformRemoteAppleWatch::SDKDirectoryInfo(file_spec));
- return FileSpec::eEnumerateDirectoryResultNext;
-}
-
-bool PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded() {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
- if (m_sdk_directory_infos.empty()) {
- const char *device_support_dir = GetDeviceSupportDirectory();
- if (log) {
- log->Printf("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded "
- "Got DeviceSupport directory %s",
- device_support_dir);
- }
- if (device_support_dir) {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
-
- SDKDirectoryInfoCollection builtin_sdk_directory_infos;
- FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
- find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &builtin_sdk_directory_infos);
-
- // Only add SDK directories that have symbols in them, some SDKs only
- // contain
- // developer disk images and no symbols, so they aren't useful to us.
- FileSpec sdk_symbols_symlink_fspec;
- for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
- sdk_symbols_symlink_fspec = sdk_directory_info.directory;
- sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal");
- if (sdk_symbols_symlink_fspec.Exists()) {
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log) {
- log->Printf("PlatformRemoteAppleWatch::"
- "UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
- "directory %s",
- sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- } else {
- sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
- if (sdk_symbols_symlink_fspec.Exists())
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log) {
- log->Printf("PlatformRemoteAppleWatch::"
- "UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
- "directory %s",
- sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- }
-
- const uint32_t num_installed = m_sdk_directory_infos.size();
- FileSpec local_sdk_cache(
- "~/Library/Developer/Xcode/watchOS DeviceSupport", true);
- if (!local_sdk_cache.Exists()) {
- local_sdk_cache =
- FileSpec("~/Library/Developer/Xcode/watch OS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists()) {
- local_sdk_cache =
- FileSpec("~/Library/Developer/Xcode/WatchOS DeviceSupport", true);
- }
- if (!local_sdk_cache.Exists()) {
- local_sdk_cache =
- FileSpec("~/Library/Developer/Xcode/Watch OS DeviceSupport", true);
- }
- if (local_sdk_cache.Exists()) {
- if (log) {
- log->Printf("PlatformRemoteAppleWatch::"
- "UpdateSDKDirectoryInfosIfNeeded searching %s for "
- "additional SDKs",
- local_sdk_cache.GetPath().c_str());
- }
- char path[PATH_MAX];
- if (local_sdk_cache.GetPath(path, sizeof(path))) {
- FileSpec::EnumerateDirectory(
- path, find_directories, find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &m_sdk_directory_infos);
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
- m_sdk_directory_infos[i].user_cached = true;
- if (log) {
- log->Printf("PlatformRemoteAppleWatch::"
- "UpdateSDKDirectoryInfosIfNeeded user SDK directory "
- "%s",
- m_sdk_directory_infos[i].directory.GetPath().c_str());
- }
- }
- }
- }
- }
- }
- return !m_sdk_directory_infos.empty();
-}
-
-const PlatformRemoteAppleWatch::SDKDirectoryInfo *
-PlatformRemoteAppleWatch::GetSDKDirectoryForCurrentOSVersion() {
- uint32_t i;
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
-
- // Check to see if the user specified a build string. If they did, then
- // be sure to match it.
- std::vector<bool> check_sdk_info(num_sdk_infos, true);
- ConstString build(m_sdk_build);
- if (build) {
- for (i = 0; i < num_sdk_infos; ++i)
- check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
- }
-
- // If we are connected we can find the version of the OS the platform
- // us running on and select the right SDK
- uint32_t major, minor, update;
- if (GetOSVersion(major, minor, update)) {
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- // First try for an exact match of major, minor and update
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor &&
- m_sdk_directory_infos[i].version_update == update) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // First try for an exact match of major and minor
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // Lastly try to match of major version only..
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- }
- } else if (build) {
- // No version, just a build number, search for the first one that matches
- for (i = 0; i < num_sdk_infos; ++i)
- if (check_sdk_info[i])
- return &m_sdk_directory_infos[i];
- }
- }
- return nullptr;
-}
-
-const PlatformRemoteAppleWatch::SDKDirectoryInfo *
-PlatformRemoteAppleWatch::GetSDKDirectoryForLatestOSVersion() {
- const PlatformRemoteAppleWatch::SDKDirectoryInfo *result = nullptr;
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (sdk_dir_info.version_major != UINT32_MAX) {
- if (result == nullptr ||
- sdk_dir_info.version_major > result->version_major) {
- result = &sdk_dir_info;
- } else if (sdk_dir_info.version_major == result->version_major) {
- if (sdk_dir_info.version_minor > result->version_minor) {
- result = &sdk_dir_info;
- } else if (sdk_dir_info.version_minor == result->version_minor) {
- if (sdk_dir_info.version_update > result->version_update) {
- result = &sdk_dir_info;
- }
- }
- }
- }
- }
- }
- return result;
-}
-
-const char *PlatformRemoteAppleWatch::GetDeviceSupportDirectory() {
- if (m_device_support_directory.empty()) {
- const char *device_support_dir = GetDeveloperDirectory();
- if (device_support_dir) {
- m_device_support_directory.assign(device_support_dir);
- m_device_support_directory.append(
- "/Platforms/watchOS.platform/DeviceSupport");
- FileSpec platform_device_support_dir(m_device_support_directory, true);
- if (!platform_device_support_dir.Exists()) {
- std::string alt_platform_dirname = device_support_dir;
- alt_platform_dirname.append(
- "/Platforms/WatchOS.platform/DeviceSupport");
- FileSpec alt_platform_device_support_dir(m_device_support_directory,
- true);
- if (alt_platform_device_support_dir.Exists()) {
- m_device_support_directory = alt_platform_dirname;
- }
- }
- } else {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory.assign(1, '\0');
- }
- }
- // We should have put a single NULL character into m_device_support_directory
- // or it should have a valid path if the code gets here
- assert(m_device_support_directory.empty() == false);
- if (m_device_support_directory[0])
- return m_device_support_directory.c_str();
- return nullptr;
-}
-
-const char *PlatformRemoteAppleWatch::GetDeviceSupportDirectoryForOSVersion() {
- if (m_sdk_sysroot)
- return m_sdk_sysroot.GetCString();
-
- if (m_device_support_directory_for_os_version.empty()) {
- const PlatformRemoteAppleWatch::SDKDirectoryInfo *sdk_dir_info =
- GetSDKDirectoryForCurrentOSVersion();
- if (sdk_dir_info == nullptr)
- sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
- if (sdk_dir_info) {
- char path[PATH_MAX];
- if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
- m_device_support_directory_for_os_version = path;
- return m_device_support_directory_for_os_version.c_str();
- }
- } else {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory_for_os_version.assign(1, '\0');
- }
- }
- // We should have put a single NULL character into
- // m_device_support_directory_for_os_version
- // or it should have a valid path if the code gets here
- assert(m_device_support_directory_for_os_version.empty() == false);
- if (m_device_support_directory_for_os_version[0])
- return m_device_support_directory_for_os_version.c_str();
- return nullptr;
-}
-
-uint32_t
-PlatformRemoteAppleWatch::FindFileInAllSDKs(const char *platform_file_path,
- FileSpecList &file_list) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (platform_file_path && platform_file_path[0] &&
- UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- lldb_private::FileSpec local_file;
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
- m_sdk_directory_infos[sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
- file_list.Append(local_file);
- }
- }
- }
- return file_list.GetSize();
-}
-
-bool PlatformRemoteAppleWatch::GetFileInSDK(
- const char *platform_file_path, uint32_t sdk_idx,
- lldb_private::FileSpec &local_file) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (sdk_idx < m_sdk_directory_infos.size()) {
- std::string sdkroot_path =
- m_sdk_directory_infos[sdk_idx].directory.GetPath();
- if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
- // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
- // the
- // SDK root directory and the file path.
-
- const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
- for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
- local_file.SetFile(sdkroot_path, false);
- if (paths_to_try[i][0] != '\0')
- local_file.AppendPathComponent(paths_to_try[i]);
- local_file.AppendPathComponent(platform_file_path);
- local_file.ResolvePath();
- if (local_file.Exists()) {
- if (log)
- log->Printf("Found a copy of %s in the SDK dir %s/%s",
- platform_file_path, sdkroot_path.c_str(),
- paths_to_try[i]);
- return true;
- }
- local_file.Clear();
- }
- }
- }
- return false;
-}
-
-Error PlatformRemoteAppleWatch::GetSymbolFile(const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- Error error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- char resolved_path[PATH_MAX];
-
- const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
- if (os_version_dir) {
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists()) {
- if (log) {
- log->Printf("Found a copy of %s in the DeviceSupport dir %s",
- platform_file_path, os_version_dir);
- }
- return error;
- }
-
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
- os_version_dir, platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists()) {
- if (log) {
- log->Printf(
- "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
- platform_file_path, os_version_dir);
- }
- return error;
- }
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
- os_version_dir, platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists()) {
- if (log) {
- log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
- platform_file_path, os_version_dir);
- }
- return error;
- }
- }
- local_file = platform_file;
- if (local_file.Exists())
- return error;
-
- error.SetErrorStringWithFormat(
- "unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path, GetPluginName().GetCString());
- } else {
- error.SetErrorString("invalid platform file argument");
- }
- return error;
-}
-
-Error PlatformRemoteAppleWatch::GetSharedModule(
- const ModuleSpec &module_spec, lldb_private::Process *process,
- ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
- // For Apple Watch, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
- const FileSpec &platform_file = module_spec.GetFileSpec();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
-
- Error error;
- char platform_file_path[PATH_MAX];
-
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- ModuleSpec platform_module_spec(module_spec);
-
- UpdateSDKDirectoryInfosIfNeeded();
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
-
- // If we are connected we migth be able to correctly deduce the SDK
- // directory
- // using the OS build.
- const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
- if (connected_sdk_idx < num_sdk_infos) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[connected_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, connected_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
- if (module_sp) {
- m_last_module_sdk_idx = connected_sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
-
- // Try the last SDK index if it is set as most files from an SDK
- // will tend to be valid in that same SDK.
- if (m_last_module_sdk_idx < num_sdk_infos) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[m_last_module_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
- if (module_sp) {
- error.Clear();
- return error;
- }
- }
- }
-
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
- if (m_last_module_sdk_idx == sdk_idx) {
- // Skip the last module SDK index if we already searched
- // it above
- continue;
- }
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, sdk_idx,
- platform_module_spec.GetFileSpec())) {
- // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
-
- error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
- if (module_sp) {
- // Remember the index of the last SDK that we found a file
- // in in case the wrong SDK was selected.
- m_last_module_sdk_idx = sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
- }
- // Not the module we are looking for... Nothing to see here...
- module_sp.reset();
-
- // This may not be an SDK-related module. Try whether we can bring in the
- // thing to our local cache.
- error = GetSharedModuleWithLocalCache(module_spec, module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
- if (error.Success())
- return error;
-
- // See if the file is present in any of the module_search_paths_ptr
- // directories.
- if (!module_sp && module_search_paths_ptr && platform_file) {
- // create a vector of all the file / directory names in platform_file
- // e.g. this might be
- // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
- //
- // We'll need to look in the module_search_paths_ptr directories for
- // both "UIFoundation" and "UIFoundation.framework" -- most likely the
- // latter will be the one we find there.
-
- FileSpec platform_pull_apart(platform_file);
- std::vector<std::string> path_parts;
- ConstString unix_root_dir("/");
- while (true) {
- ConstString part = platform_pull_apart.GetLastPathComponent();
- platform_pull_apart.RemoveLastPathComponent();
- if (part.IsEmpty() || part == unix_root_dir)
- break;
- path_parts.push_back(part.AsCString());
- }
- const size_t path_parts_size = path_parts.size();
-
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i = 0; i < num_module_search_paths; ++i) {
- // Create a new FileSpec with this module_search_paths_ptr
- // plus just the filename ("UIFoundation"), then the parent
- // dir plus filename ("UIFoundation.framework/UIFoundation")
- // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
-
- for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
- FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
-
- // Add the components backwards. For
- // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
- // path_parts is
- // [0] UIFoundation
- // [1] UIFoundation.framework
- // [2] PrivateFrameworks
- //
- // and if 'j' is 2, we want to append path_parts[1] and then
- // path_parts[0], aka
- // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
- // path.
-
- for (int k = j; k >= 0; --k) {
- path_to_try.AppendPathComponent(path_parts[k]);
- }
-
- if (path_to_try.Exists()) {
- ModuleSpec new_module_spec(module_spec);
- new_module_spec.GetFileSpec() = path_to_try;
- Error new_error(Platform::GetSharedModule(
- new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp) {
- module_sp->SetPlatformFileSpec(path_to_try);
- return new_error;
- }
- }
- }
- }
- }
-
- const bool always_create = false;
- error = ModuleList::GetSharedModule(
- module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
- did_create_ptr, always_create);
-
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
-}
+//------------------------------------------------------------------
+/// Default Constructor
+//------------------------------------------------------------------
+PlatformRemoteAppleWatch::PlatformRemoteAppleWatch()
+ : PlatformRemoteDarwinDevice() {}
bool PlatformRemoteAppleWatch::GetSupportedArchitectureAtIndex(uint32_t idx,
ArchSpec &arch) {
@@ -923,23 +295,13 @@ bool PlatformRemoteAppleWatch::GetSupportedArchitectureAtIndex(uint32_t idx,
return false;
}
-uint32_t PlatformRemoteAppleWatch::GetConnectedSDKIndex() {
- if (IsConnected()) {
- if (m_connected_module_sdk_idx == UINT32_MAX) {
- std::string build;
- if (GetRemoteOSBuildString(build)) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
- build.c_str())) {
- m_connected_module_sdk_idx = i;
- }
- }
- }
- }
- } else {
- m_connected_module_sdk_idx = UINT32_MAX;
- }
- return m_connected_module_sdk_idx;
+void PlatformRemoteAppleWatch::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
+{
+ dirnames.clear();
+ dirnames.push_back("watchOS DeviceSupport");
+}
+
+std::string PlatformRemoteAppleWatch::GetPlatformName ()
+{
+ return "WatchOS.platform";
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
index d6c91140171b..93be55b595f8 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
@@ -19,11 +19,11 @@
// Project includes
#include "lldb/Utility/FileSpec.h"
-#include "PlatformDarwin.h"
+#include "PlatformRemoteDarwinDevice.h"
#include "llvm/Support/FileSystem.h"
-class PlatformRemoteAppleWatch : public PlatformDarwin {
+class PlatformRemoteAppleWatch : public PlatformRemoteDarwinDevice {
public:
PlatformRemoteAppleWatch();
@@ -44,9 +44,11 @@ public:
static const char *GetDescriptionStatic();
//------------------------------------------------------------
- // Class Methods
+ // lldb_private::Platform functions
//------------------------------------------------------------
+ const char *GetDescription() override { return GetDescriptionStatic(); }
+
//------------------------------------------------------------
// lldb_private::PluginInterface functions
//------------------------------------------------------------
@@ -59,80 +61,19 @@ public:
//------------------------------------------------------------
// lldb_private::Platform functions
//------------------------------------------------------------
- lldb_private::Error ResolveExecutable(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- void GetStatus(lldb_private::Stream &strm) override;
-
- virtual lldb_private::Error
- GetSymbolFile(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
bool GetSupportedArchitectureAtIndex(uint32_t idx,
lldb_private::ArchSpec &arch) override;
- void
- AddClangModuleCompilationOptions(lldb_private::Target *target,
- std::vector<std::string> &options) override {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
- target, options, PlatformDarwin::SDKType::iPhoneOS);
- }
-
protected:
- struct SDKDirectoryInfo {
- SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
- lldb_private::FileSpec directory;
- lldb_private::ConstString build;
- uint32_t version_major;
- uint32_t version_minor;
- uint32_t version_update;
- bool user_cached;
- };
- typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
- std::mutex m_sdk_dir_mutex;
- SDKDirectoryInfoCollection m_sdk_directory_infos;
- std::string m_device_support_directory;
- std::string m_device_support_directory_for_os_version;
- std::string m_build_update;
- uint32_t m_last_module_sdk_idx;
- uint32_t m_connected_module_sdk_idx;
- bool UpdateSDKDirectoryInfosIfNeeded();
-
- const char *GetDeviceSupportDirectory();
-
- const char *GetDeviceSupportDirectoryForOSVersion();
-
- const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
-
- const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
-
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetContainedFilesIntoVectorOfStringsCallback(
- void *baton, llvm::sys::fs::file_type ft,
- const lldb_private::FileSpec &file_spec);
-
- uint32_t FindFileInAllSDKs(const char *platform_file_path,
- lldb_private::FileSpecList &file_list);
-
- bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
- lldb_private::FileSpec &local_file);
+ //------------------------------------------------------------
+ // lldb_private::PlatformRemoteDarwinDevice functions
+ //------------------------------------------------------------
- uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
- lldb_private::FileSpecList &file_list);
+ void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
- uint32_t GetConnectedSDKIndex();
+ std::string GetPlatformName () override;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleWatch);
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
new file mode 100644
index 000000000000..0302e7b3aaf8
--- /dev/null
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
@@ -0,0 +1,712 @@
+//===-- PlatformRemoteDarwinDevice.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PlatformRemoteDarwinDevice.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+PlatformRemoteDarwinDevice::SDKDirectoryInfo::SDKDirectoryInfo(
+ const lldb_private::FileSpec &sdk_dir)
+ : directory(sdk_dir), build(), version_major(0), version_minor(0),
+ version_update(0), user_cached(false) {
+ llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
+ llvm::StringRef build_str;
+ std::tie(version_major, version_minor, version_update, build_str) =
+ ParseVersionBuildDir(dirname_str);
+ build.SetString(build_str);
+}
+
+//------------------------------------------------------------------
+/// Default Constructor
+//------------------------------------------------------------------
+PlatformRemoteDarwinDevice::PlatformRemoteDarwinDevice()
+ : PlatformDarwin(false), // This is a remote platform
+ m_sdk_directory_infos(), m_device_support_directory(),
+ m_device_support_directory_for_os_version(), m_build_update(),
+ m_last_module_sdk_idx(UINT32_MAX),
+ m_connected_module_sdk_idx(UINT32_MAX) {}
+
+//------------------------------------------------------------------
+/// Destructor.
+///
+/// The destructor is virtual since this class is designed to be
+/// inherited from by the plug-in instance.
+//------------------------------------------------------------------
+PlatformRemoteDarwinDevice::~PlatformRemoteDarwinDevice() {}
+
+void PlatformRemoteDarwinDevice::GetStatus(Stream &strm) {
+ Platform::GetStatus(strm);
+ const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
+ if (sdk_directory)
+ strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
+ else
+ strm.PutCString(" SDK Path: error: unable to locate SDK\n");
+
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
+ sdk_dir_info.directory.GetPath().c_str());
+ }
+}
+
+Error PlatformRemoteDarwinDevice::ResolveExecutable(
+ const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Error error;
+ // Nothing special to do here, just use the actual file and architecture
+
+ ModuleSpec resolved_module_spec(ms);
+
+ // Resolve any executable within a bundle on MacOSX
+ // TODO: verify that this handles shallow bundles, if not then implement one
+ // ourselves
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (resolved_module_spec.GetArchitecture().IsValid() ||
+ resolved_module_spec.GetUUID().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
+ }
+ // No valid architecture was specified or the exact ARM slice wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
+ idx, resolved_module_spec.GetArchitecture());
+ ++idx) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ NULL, NULL, NULL);
+ // Did we find an executable using one of the
+ if (error.Success()) {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
+ }
+
+ if (idx > 0)
+ arch_names.PutCString(", ");
+ arch_names.PutCString(
+ resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+
+ if (error.Fail() || !exe_module_sp) {
+ if (resolved_module_spec.GetFileSpec().Readable()) {
+ error.SetErrorStringWithFormat(
+ "'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(), arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' is not readable",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' does not exist",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+
+ return error;
+}
+
+FileSpec::EnumerateDirectoryResult
+PlatformRemoteDarwinDevice::GetContainedFilesIntoVectorOfStringsCallback(
+ void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
+ ((PlatformRemoteDarwinDevice::SDKDirectoryInfoCollection *)baton)
+ ->push_back(PlatformRemoteDarwinDevice::SDKDirectoryInfo(file_spec));
+ return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
+ if (m_sdk_directory_infos.empty()) {
+ // A --sysroot option was supplied - add it to our list of SDKs to check
+ if (m_sdk_sysroot) {
+ FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString(), true);
+ const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
+ m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
+ if (log) {
+ log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded added "
+ "--sysroot SDK directory %s",
+ m_sdk_sysroot.GetCString());
+ }
+ return true;
+ }
+ const char *device_support_dir = GetDeviceSupportDirectory();
+ if (log) {
+ log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded Got "
+ "DeviceSupport directory %s",
+ device_support_dir);
+ }
+ if (device_support_dir) {
+ const bool find_directories = true;
+ const bool find_files = false;
+ const bool find_other = false;
+
+ SDKDirectoryInfoCollection builtin_sdk_directory_infos;
+ FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
+ find_files, find_other,
+ GetContainedFilesIntoVectorOfStringsCallback,
+ &builtin_sdk_directory_infos);
+
+ // Only add SDK directories that have symbols in them, some SDKs only
+ // contain
+ // developer disk images and no symbols, so they aren't useful to us.
+ FileSpec sdk_symbols_symlink_fspec;
+ for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
+ sdk_symbols_symlink_fspec = sdk_directory_info.directory;
+ sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
+ if (sdk_symbols_symlink_fspec.Exists()) {
+ m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log) {
+ log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
+ "added builtin SDK directory %s",
+ sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
+ }
+ }
+
+ std::vector<std::string> device_support_dirnames;
+ GetDeviceSupportDirectoryNames (device_support_dirnames);
+
+ for (std::string &dirname : device_support_dirnames)
+ {
+ const uint32_t num_installed = m_sdk_directory_infos.size();
+ std::string local_sdk_cache_str = "~/Library/Developer/Xcode/";
+ local_sdk_cache_str += dirname;
+ FileSpec local_sdk_cache(local_sdk_cache_str.c_str(), true);
+ if (local_sdk_cache.Exists()) {
+ if (log) {
+ log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
+ "searching %s for additional SDKs",
+ local_sdk_cache.GetPath().c_str());
+ }
+ char path[PATH_MAX];
+ if (local_sdk_cache.GetPath(path, sizeof(path))) {
+ FileSpec::EnumerateDirectory(
+ path, find_directories, find_files, find_other,
+ GetContainedFilesIntoVectorOfStringsCallback,
+ &m_sdk_directory_infos);
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ // First try for an exact match of major, minor and update
+ for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
+ m_sdk_directory_infos[i].user_cached = true;
+ if (log) {
+ log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
+ "user SDK directory %s",
+ m_sdk_directory_infos[i].directory.GetPath().c_str());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return !m_sdk_directory_infos.empty();
+}
+
+const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
+PlatformRemoteDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
+ uint32_t i;
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+
+ // Check to see if the user specified a build string. If they did, then
+ // be sure to match it.
+ std::vector<bool> check_sdk_info(num_sdk_infos, true);
+ ConstString build(m_sdk_build);
+ if (build) {
+ for (i = 0; i < num_sdk_infos; ++i)
+ check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
+ }
+
+ // If we are connected we can find the version of the OS the platform
+ // us running on and select the right SDK
+ uint32_t major, minor, update;
+ if (GetOSVersion(major, minor, update)) {
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ // First try for an exact match of major, minor and update
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major &&
+ m_sdk_directory_infos[i].version_minor == minor &&
+ m_sdk_directory_infos[i].version_update == update) {
+ return &m_sdk_directory_infos[i];
+ }
+ }
+ }
+ // First try for an exact match of major and minor
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major &&
+ m_sdk_directory_infos[i].version_minor == minor) {
+ return &m_sdk_directory_infos[i];
+ }
+ }
+ }
+ // Lastly try to match of major version only..
+ for (i = 0; i < num_sdk_infos; ++i) {
+ if (check_sdk_info[i]) {
+ if (m_sdk_directory_infos[i].version_major == major) {
+ return &m_sdk_directory_infos[i];
+ }
+ }
+ }
+ }
+ } else if (build) {
+ // No version, just a build number, search for the first one that matches
+ for (i = 0; i < num_sdk_infos; ++i)
+ if (check_sdk_info[i])
+ return &m_sdk_directory_infos[i];
+ }
+ }
+ return NULL;
+}
+
+const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
+PlatformRemoteDarwinDevice::GetSDKDirectoryForLatestOSVersion() {
+ const PlatformRemoteDarwinDevice::SDKDirectoryInfo *result = NULL;
+ if (UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ // First try for an exact match of major, minor and update
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ if (sdk_dir_info.version_major != UINT32_MAX) {
+ if (result == NULL ||
+ sdk_dir_info.version_major > result->version_major) {
+ result = &sdk_dir_info;
+ } else if (sdk_dir_info.version_major == result->version_major) {
+ if (sdk_dir_info.version_minor > result->version_minor) {
+ result = &sdk_dir_info;
+ } else if (sdk_dir_info.version_minor == result->version_minor) {
+ if (sdk_dir_info.version_update > result->version_update) {
+ result = &sdk_dir_info;
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
+
+const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectory() {
+ std::string platform_dir = "/Platforms/" + GetPlatformName() + "/DeviceSupport";
+ if (m_device_support_directory.empty()) {
+ const char *device_support_dir = GetDeveloperDirectory();
+ if (device_support_dir) {
+ m_device_support_directory.assign(device_support_dir);
+ m_device_support_directory.append(platform_dir.c_str());
+ } else {
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_device_support_directory.assign(1, '\0');
+ }
+ }
+ // We should have put a single NULL character into m_device_support_directory
+ // or it should have a valid path if the code gets here
+ assert(m_device_support_directory.empty() == false);
+ if (m_device_support_directory[0])
+ return m_device_support_directory.c_str();
+ return NULL;
+}
+
+const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectoryForOSVersion() {
+ if (m_sdk_sysroot)
+ return m_sdk_sysroot.GetCString();
+
+ if (m_device_support_directory_for_os_version.empty()) {
+ const PlatformRemoteDarwinDevice::SDKDirectoryInfo *sdk_dir_info =
+ GetSDKDirectoryForCurrentOSVersion();
+ if (sdk_dir_info == NULL)
+ sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
+ if (sdk_dir_info) {
+ char path[PATH_MAX];
+ if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
+ m_device_support_directory_for_os_version = path;
+ return m_device_support_directory_for_os_version.c_str();
+ }
+ } else {
+ // Assign a single NULL character so we know we tried to find the device
+ // support directory and we don't keep trying to find it over and over.
+ m_device_support_directory_for_os_version.assign(1, '\0');
+ }
+ }
+ // We should have put a single NULL character into
+ // m_device_support_directory_for_os_version
+ // or it should have a valid path if the code gets here
+ assert(m_device_support_directory_for_os_version.empty() == false);
+ if (m_device_support_directory_for_os_version[0])
+ return m_device_support_directory_for_os_version.c_str();
+ return NULL;
+}
+
+uint32_t PlatformRemoteDarwinDevice::FindFileInAllSDKs(const char *platform_file_path,
+ FileSpecList &file_list) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (platform_file_path && platform_file_path[0] &&
+ UpdateSDKDirectoryInfosIfNeeded()) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ lldb_private::FileSpec local_file;
+ // First try for an exact match of major, minor and update
+ for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
+ LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
+ m_sdk_directory_infos[sdk_idx].directory);
+ if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
+ file_list.Append(local_file);
+ }
+ }
+ }
+ return file_list.GetSize();
+}
+
+bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path,
+ uint32_t sdk_idx,
+ lldb_private::FileSpec &local_file) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (sdk_idx < m_sdk_directory_infos.size()) {
+ std::string sdkroot_path =
+ m_sdk_directory_infos[sdk_idx].directory.GetPath();
+ local_file.Clear();
+
+ if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
+ // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
+ // the
+ // SDK root directory and the file path.
+
+ const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
+ for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
+ local_file.SetFile(sdkroot_path, false);
+ if (paths_to_try[i][0] != '\0')
+ local_file.AppendPathComponent(paths_to_try[i]);
+ local_file.AppendPathComponent(platform_file_path);
+ local_file.ResolvePath();
+ if (local_file.Exists()) {
+ if (log)
+ log->Printf("Found a copy of %s in the SDK dir %s/%s",
+ platform_file_path, sdkroot_path.c_str(),
+ paths_to_try[i]);
+ return true;
+ }
+ local_file.Clear();
+ }
+ }
+ }
+ return false;
+}
+
+Error PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ Error error;
+ char platform_file_path[PATH_MAX];
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ char resolved_path[PATH_MAX];
+
+ const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
+ if (os_version_dir) {
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
+ platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf("Found a copy of %s in the DeviceSupport dir %s",
+ platform_file_path, os_version_dir);
+ }
+ return error;
+ }
+
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
+ os_version_dir, platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf(
+ "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
+ platform_file_path, os_version_dir);
+ }
+ return error;
+ }
+ ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
+ os_version_dir, platform_file_path);
+
+ local_file.SetFile(resolved_path, true);
+ if (local_file.Exists()) {
+ if (log) {
+ log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
+ platform_file_path, os_version_dir);
+ }
+ return error;
+ }
+ }
+ local_file = platform_file;
+ if (local_file.Exists())
+ return error;
+
+ error.SetErrorStringWithFormat(
+ "unable to locate a platform file for '%s' in platform '%s'",
+ platform_file_path, GetPluginName().GetCString());
+ } else {
+ error.SetErrorString("invalid platform file argument");
+ }
+ return error;
+}
+
+Error PlatformRemoteDarwinDevice::GetSharedModule(
+ const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) {
+ // For iOS, the SDK files are all cached locally on the host
+ // system. So first we ask for the file in the cached SDK,
+ // then we attempt to get a shared module for the right architecture
+ // with the right UUID.
+ const FileSpec &platform_file = module_spec.GetFileSpec();
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+
+ Error error;
+ char platform_file_path[PATH_MAX];
+
+ if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
+ ModuleSpec platform_module_spec(module_spec);
+
+ UpdateSDKDirectoryInfosIfNeeded();
+
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+
+ // If we are connected we migth be able to correctly deduce the SDK
+ // directory
+ // using the OS build.
+ const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
+ if (connected_sdk_idx < num_sdk_infos) {
+ LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
+ m_sdk_directory_infos[connected_sdk_idx].directory);
+ if (GetFileInSDK(platform_file_path, connected_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, NULL);
+ if (module_sp) {
+ m_last_module_sdk_idx = connected_sdk_idx;
+ error.Clear();
+ return error;
+ }
+ }
+ }
+
+ // Try the last SDK index if it is set as most files from an SDK
+ // will tend to be valid in that same SDK.
+ if (m_last_module_sdk_idx < num_sdk_infos) {
+ LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
+ m_sdk_directory_infos[m_last_module_sdk_idx].directory);
+ if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, NULL);
+ if (module_sp) {
+ error.Clear();
+ return error;
+ }
+ }
+ }
+
+ // First try for an exact match of major, minor and update:
+ // If a particalar SDK version was specified via --version or --build, look
+ // for a match on disk.
+ const SDKDirectoryInfo *current_sdk_info =
+ GetSDKDirectoryForCurrentOSVersion();
+ const uint32_t current_sdk_idx =
+ GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
+ if (current_sdk_idx < num_sdk_infos &&
+ current_sdk_idx != m_last_module_sdk_idx) {
+ LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
+ m_sdk_directory_infos[current_sdk_idx].directory);
+ if (GetFileInSDK(platform_file_path, current_sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ module_sp.reset();
+ error = ResolveExecutable(platform_module_spec, module_sp, NULL);
+ if (module_sp) {
+ m_last_module_sdk_idx = current_sdk_idx;
+ error.Clear();
+ return error;
+ }
+ }
+ }
+
+ // Second try all SDKs that were found.
+ for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
+ if (m_last_module_sdk_idx == sdk_idx) {
+ // Skip the last module SDK index if we already searched
+ // it above
+ continue;
+ }
+ LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
+ m_sdk_directory_infos[sdk_idx].directory);
+ if (GetFileInSDK(platform_file_path, sdk_idx,
+ platform_module_spec.GetFileSpec())) {
+ // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
+
+ error = ResolveExecutable(platform_module_spec, module_sp, NULL);
+ if (module_sp) {
+ // Remember the index of the last SDK that we found a file
+ // in in case the wrong SDK was selected.
+ m_last_module_sdk_idx = sdk_idx;
+ error.Clear();
+ return error;
+ }
+ }
+ }
+ }
+ // Not the module we are looking for... Nothing to see here...
+ module_sp.reset();
+
+ // This may not be an SDK-related module. Try whether we can bring in the
+ // thing to our local cache.
+ error = GetSharedModuleWithLocalCache(module_spec, module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr, did_create_ptr);
+ if (error.Success())
+ return error;
+
+ // See if the file is present in any of the module_search_paths_ptr
+ // directories.
+ if (!module_sp && module_search_paths_ptr && platform_file) {
+ // create a vector of all the file / directory names in platform_file
+ // e.g. this might be
+ // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
+ //
+ // We'll need to look in the module_search_paths_ptr directories for
+ // both "UIFoundation" and "UIFoundation.framework" -- most likely the
+ // latter will be the one we find there.
+
+ FileSpec platform_pull_apart(platform_file);
+ std::vector<std::string> path_parts;
+ ConstString unix_root_dir("/");
+ while (true) {
+ ConstString part = platform_pull_apart.GetLastPathComponent();
+ platform_pull_apart.RemoveLastPathComponent();
+ if (part.IsEmpty() || part == unix_root_dir)
+ break;
+ path_parts.push_back(part.AsCString());
+ }
+ const size_t path_parts_size = path_parts.size();
+
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i = 0; i < num_module_search_paths; ++i) {
+ LLDB_LOGV(log, "searching for binary in search-path {0}",
+ module_search_paths_ptr->GetFileSpecAtIndex(i));
+ // Create a new FileSpec with this module_search_paths_ptr
+ // plus just the filename ("UIFoundation"), then the parent
+ // dir plus filename ("UIFoundation.framework/UIFoundation")
+ // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
+
+ for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
+ FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
+
+ // Add the components backwards. For
+ // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
+ // path_parts is
+ // [0] UIFoundation
+ // [1] UIFoundation.framework
+ // [2] PrivateFrameworks
+ //
+ // and if 'j' is 2, we want to append path_parts[1] and then
+ // path_parts[0], aka
+ // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
+ // path.
+
+ for (int k = j; k >= 0; --k) {
+ path_to_try.AppendPathComponent(path_parts[k]);
+ }
+
+ if (path_to_try.Exists()) {
+ ModuleSpec new_module_spec(module_spec);
+ new_module_spec.GetFileSpec() = path_to_try;
+ Error new_error(Platform::GetSharedModule(
+ new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp) {
+ module_sp->SetPlatformFileSpec(path_to_try);
+ return new_error;
+ }
+ }
+ }
+ }
+ }
+
+ const bool always_create = false;
+ error = ModuleList::GetSharedModule(
+ module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
+ did_create_ptr, always_create);
+
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(platform_file);
+
+ return error;
+}
+
+uint32_t PlatformRemoteDarwinDevice::GetConnectedSDKIndex() {
+ if (IsConnected()) {
+ if (m_connected_module_sdk_idx == UINT32_MAX) {
+ std::string build;
+ if (GetRemoteOSBuildString(build)) {
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ for (uint32_t i = 0; i < num_sdk_infos; ++i) {
+ const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
+ if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
+ build.c_str())) {
+ m_connected_module_sdk_idx = i;
+ }
+ }
+ }
+ }
+ } else {
+ m_connected_module_sdk_idx = UINT32_MAX;
+ }
+ return m_connected_module_sdk_idx;
+}
+
+uint32_t PlatformRemoteDarwinDevice::GetSDKIndexBySDKDirectoryInfo(
+ const SDKDirectoryInfo *sdk_info) {
+ if (sdk_info == NULL) {
+ return UINT32_MAX;
+ }
+
+ return sdk_info - &m_sdk_directory_infos[0];
+}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
new file mode 100644
index 000000000000..55fb4f920c66
--- /dev/null
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
@@ -0,0 +1,118 @@
+//===-- PlatformRemoteDarwinDevice.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_PlatformRemoteDarwinDevice_h_
+#define liblldb_PlatformRemoteDarwinDevice_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "PlatformDarwin.h"
+#include "lldb/Utility/FileSpec.h"
+
+#include "llvm/Support/FileSystem.h"
+
+class PlatformRemoteDarwinDevice : public PlatformDarwin {
+public:
+ PlatformRemoteDarwinDevice();
+
+ ~PlatformRemoteDarwinDevice() override;
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ lldb_private::Error ResolveExecutable(
+ const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr) override;
+
+ void GetStatus(lldb_private::Stream &strm) override;
+
+ virtual lldb_private::Error
+ GetSymbolFile(const lldb_private::FileSpec &platform_file,
+ const lldb_private::UUID *uuid_ptr,
+ lldb_private::FileSpec &local_file);
+
+ lldb_private::Error
+ GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+ lldb_private::Process *process, lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr) override;
+
+ void
+ AddClangModuleCompilationOptions(lldb_private::Target *target,
+ std::vector<std::string> &options) override {
+ return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
+ target, options, PlatformDarwin::SDKType::iPhoneOS);
+ }
+
+protected:
+ struct SDKDirectoryInfo {
+ SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
+ lldb_private::FileSpec directory;
+ lldb_private::ConstString build;
+ uint32_t version_major;
+ uint32_t version_minor;
+ uint32_t version_update;
+ bool user_cached;
+ };
+
+ typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
+
+ std::mutex m_sdk_dir_mutex;
+ SDKDirectoryInfoCollection m_sdk_directory_infos;
+ std::string m_device_support_directory;
+ std::string m_device_support_directory_for_os_version;
+ std::string m_build_update;
+ uint32_t m_last_module_sdk_idx;
+ uint32_t m_connected_module_sdk_idx;
+
+ bool UpdateSDKDirectoryInfosIfNeeded();
+
+ const char *GetDeviceSupportDirectory();
+
+ const char *GetDeviceSupportDirectoryForOSVersion();
+
+ const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
+
+ const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
+
+ static lldb_private::FileSpec::EnumerateDirectoryResult
+ GetContainedFilesIntoVectorOfStringsCallback(
+ void *baton, llvm::sys::fs::file_type ft,
+ const lldb_private::FileSpec &file_spec);
+
+ uint32_t FindFileInAllSDKs(const char *platform_file_path,
+ lldb_private::FileSpecList &file_list);
+
+ bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
+ lldb_private::FileSpec &local_file);
+
+ uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
+ lldb_private::FileSpecList &file_list);
+
+ uint32_t GetConnectedSDKIndex();
+
+ // Get index of SDK in SDKDirectoryInfoCollection by its pointer and return
+ // UINT32_MAX if that SDK not found.
+ uint32_t GetSDKIndexBySDKDirectoryInfo(const SDKDirectoryInfo *sdk_info);
+
+
+ virtual void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) = 0;
+
+ virtual std::string GetPlatformName () = 0;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformRemoteDarwinDevice);
+};
+
+#endif // liblldb_PlatformRemoteDarwinDevice_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index 9d47b2464a27..ec1109fb4b44 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -30,17 +30,6 @@
using namespace lldb;
using namespace lldb_private;
-PlatformRemoteiOS::SDKDirectoryInfo::SDKDirectoryInfo(
- const lldb_private::FileSpec &sdk_dir)
- : directory(sdk_dir), build(), version_major(0), version_minor(0),
- version_update(0), user_cached(false) {
- llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
- llvm::StringRef build_str;
- std::tie(version_major, version_minor, version_update, build_str) =
- ParseVersionBuildDir(dirname_str);
- build.SetString(build_str);
-}
-
//------------------------------------------------------------------
// Static Variables
//------------------------------------------------------------------
@@ -156,666 +145,21 @@ const char *PlatformRemoteiOS::GetDescriptionStatic() {
/// Default Constructor
//------------------------------------------------------------------
PlatformRemoteiOS::PlatformRemoteiOS()
- : PlatformDarwin(false), // This is a remote platform
- m_sdk_directory_infos(), m_device_support_directory(),
- m_device_support_directory_for_os_version(), m_build_update(),
- m_last_module_sdk_idx(UINT32_MAX),
- m_connected_module_sdk_idx(UINT32_MAX) {}
-
-//------------------------------------------------------------------
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-//------------------------------------------------------------------
-PlatformRemoteiOS::~PlatformRemoteiOS() {}
-
-void PlatformRemoteiOS::GetStatus(Stream &strm) {
- Platform::GetStatus(strm);
- const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
- if (sdk_directory)
- strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
- else
- strm.PutCString(" SDK Path: error: unable to locate SDK\n");
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
- sdk_dir_info.directory.GetPath().c_str());
- }
-}
-
-Error PlatformRemoteiOS::ResolveExecutable(
- const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
- Error error;
- // Nothing special to do here, just use the actual file and architecture
-
- ModuleSpec resolved_module_spec(ms);
-
- // Resolve any executable within a bundle on MacOSX
- // TODO: verify that this handles shallow bundles, if not then implement one
- // ourselves
- Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-
- if (resolved_module_spec.GetFileSpec().Exists()) {
- if (resolved_module_spec.GetArchitecture().IsValid() ||
- resolved_module_spec.GetUUID().IsValid()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
-
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- return error;
- exe_module_sp.reset();
- }
- // No valid architecture was specified or the exact ARM slice wasn't
- // found so ask the platform for the architectures that we should be
- // using (in the correct order) and see if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- NULL, NULL, NULL);
- // Did we find an executable using one of the
- if (error.Success()) {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(), arch_names.GetData());
- } else {
- error.SetErrorStringWithFormat(
- "'%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- } else {
- error.SetErrorStringWithFormat(
- "'%s' does not exist",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
-
- return error;
-}
-
-FileSpec::EnumerateDirectoryResult
-PlatformRemoteiOS::GetContainedFilesIntoVectorOfStringsCallback(
- void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
- ((PlatformRemoteiOS::SDKDirectoryInfoCollection *)baton)
- ->push_back(PlatformRemoteiOS::SDKDirectoryInfo(file_spec));
- return FileSpec::eEnumerateDirectoryResultNext;
-}
-
-bool PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded() {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
- if (m_sdk_directory_infos.empty()) {
- // A --sysroot option was supplied - add it to our list of SDKs to check
- if (m_sdk_sysroot) {
- FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString(), true);
- const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
- m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
- if (log) {
- log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded added "
- "--sysroot SDK directory %s",
- m_sdk_sysroot.GetCString());
- }
- return true;
- }
- const char *device_support_dir = GetDeviceSupportDirectory();
- if (log) {
- log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded Got "
- "DeviceSupport directory %s",
- device_support_dir);
- }
- if (device_support_dir) {
- const bool find_directories = true;
- const bool find_files = false;
- const bool find_other = false;
-
- SDKDirectoryInfoCollection builtin_sdk_directory_infos;
- FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
- find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &builtin_sdk_directory_infos);
-
- // Only add SDK directories that have symbols in them, some SDKs only
- // contain
- // developer disk images and no symbols, so they aren't useful to us.
- FileSpec sdk_symbols_symlink_fspec;
- for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
- sdk_symbols_symlink_fspec = sdk_directory_info.directory;
- sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
- if (sdk_symbols_symlink_fspec.Exists()) {
- m_sdk_directory_infos.push_back(sdk_directory_info);
- if (log) {
- log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
- "added builtin SDK directory %s",
- sdk_symbols_symlink_fspec.GetPath().c_str());
- }
- }
- }
-
- const uint32_t num_installed = m_sdk_directory_infos.size();
- FileSpec local_sdk_cache("~/Library/Developer/Xcode/iOS DeviceSupport",
- true);
- if (local_sdk_cache.Exists()) {
- if (log) {
- log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
- "searching %s for additional SDKs",
- local_sdk_cache.GetPath().c_str());
- }
- char path[PATH_MAX];
- if (local_sdk_cache.GetPath(path, sizeof(path))) {
- FileSpec::EnumerateDirectory(
- path, find_directories, find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &m_sdk_directory_infos);
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
- m_sdk_directory_infos[i].user_cached = true;
- if (log) {
- log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
- "user SDK directory %s",
- m_sdk_directory_infos[i].directory.GetPath().c_str());
- }
- }
- }
- }
- }
- }
- return !m_sdk_directory_infos.empty();
-}
-
-const PlatformRemoteiOS::SDKDirectoryInfo *
-PlatformRemoteiOS::GetSDKDirectoryForCurrentOSVersion() {
- uint32_t i;
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
-
- // Check to see if the user specified a build string. If they did, then
- // be sure to match it.
- std::vector<bool> check_sdk_info(num_sdk_infos, true);
- ConstString build(m_sdk_build);
- if (build) {
- for (i = 0; i < num_sdk_infos; ++i)
- check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
- }
-
- // If we are connected we can find the version of the OS the platform
- // us running on and select the right SDK
- uint32_t major, minor, update;
- if (GetOSVersion(major, minor, update)) {
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- // First try for an exact match of major, minor and update
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor &&
- m_sdk_directory_infos[i].version_update == update) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // First try for an exact match of major and minor
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major &&
- m_sdk_directory_infos[i].version_minor == minor) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- // Lastly try to match of major version only..
- for (i = 0; i < num_sdk_infos; ++i) {
- if (check_sdk_info[i]) {
- if (m_sdk_directory_infos[i].version_major == major) {
- return &m_sdk_directory_infos[i];
- }
- }
- }
- }
- } else if (build) {
- // No version, just a build number, search for the first one that matches
- for (i = 0; i < num_sdk_infos; ++i)
- if (check_sdk_info[i])
- return &m_sdk_directory_infos[i];
- }
- }
- return NULL;
-}
-
-const PlatformRemoteiOS::SDKDirectoryInfo *
-PlatformRemoteiOS::GetSDKDirectoryForLatestOSVersion() {
- const PlatformRemoteiOS::SDKDirectoryInfo *result = NULL;
- if (UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (sdk_dir_info.version_major != UINT32_MAX) {
- if (result == NULL ||
- sdk_dir_info.version_major > result->version_major) {
- result = &sdk_dir_info;
- } else if (sdk_dir_info.version_major == result->version_major) {
- if (sdk_dir_info.version_minor > result->version_minor) {
- result = &sdk_dir_info;
- } else if (sdk_dir_info.version_minor == result->version_minor) {
- if (sdk_dir_info.version_update > result->version_update) {
- result = &sdk_dir_info;
- }
- }
- }
- }
- }
- }
- return result;
-}
-
-const char *PlatformRemoteiOS::GetDeviceSupportDirectory() {
- if (m_device_support_directory.empty()) {
- const char *device_support_dir = GetDeveloperDirectory();
- if (device_support_dir) {
- m_device_support_directory.assign(device_support_dir);
- m_device_support_directory.append(
- "/Platforms/iPhoneOS.platform/DeviceSupport");
- } else {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory.assign(1, '\0');
- }
- }
- // We should have put a single NULL character into m_device_support_directory
- // or it should have a valid path if the code gets here
- assert(m_device_support_directory.empty() == false);
- if (m_device_support_directory[0])
- return m_device_support_directory.c_str();
- return NULL;
-}
-
-const char *PlatformRemoteiOS::GetDeviceSupportDirectoryForOSVersion() {
- if (m_sdk_sysroot)
- return m_sdk_sysroot.GetCString();
-
- if (m_device_support_directory_for_os_version.empty()) {
- const PlatformRemoteiOS::SDKDirectoryInfo *sdk_dir_info =
- GetSDKDirectoryForCurrentOSVersion();
- if (sdk_dir_info == NULL)
- sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
- if (sdk_dir_info) {
- char path[PATH_MAX];
- if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
- m_device_support_directory_for_os_version = path;
- return m_device_support_directory_for_os_version.c_str();
- }
- } else {
- // Assign a single NULL character so we know we tried to find the device
- // support directory and we don't keep trying to find it over and over.
- m_device_support_directory_for_os_version.assign(1, '\0');
- }
- }
- // We should have put a single NULL character into
- // m_device_support_directory_for_os_version
- // or it should have a valid path if the code gets here
- assert(m_device_support_directory_for_os_version.empty() == false);
- if (m_device_support_directory_for_os_version[0])
- return m_device_support_directory_for_os_version.c_str();
- return NULL;
-}
-
-uint32_t PlatformRemoteiOS::FindFileInAllSDKs(const char *platform_file_path,
- FileSpecList &file_list) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (platform_file_path && platform_file_path[0] &&
- UpdateSDKDirectoryInfosIfNeeded()) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- lldb_private::FileSpec local_file;
- // First try for an exact match of major, minor and update
- for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
- m_sdk_directory_infos[sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
- file_list.Append(local_file);
- }
- }
- }
- return file_list.GetSize();
-}
-
-bool PlatformRemoteiOS::GetFileInSDK(const char *platform_file_path,
- uint32_t sdk_idx,
- lldb_private::FileSpec &local_file) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (sdk_idx < m_sdk_directory_infos.size()) {
- std::string sdkroot_path =
- m_sdk_directory_infos[sdk_idx].directory.GetPath();
- local_file.Clear();
-
- if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
- // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
- // the
- // SDK root directory and the file path.
-
- const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
- for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
- local_file.SetFile(sdkroot_path, false);
- if (paths_to_try[i][0] != '\0')
- local_file.AppendPathComponent(paths_to_try[i]);
- local_file.AppendPathComponent(platform_file_path);
- local_file.ResolvePath();
- if (local_file.Exists()) {
- if (log)
- log->Printf("Found a copy of %s in the SDK dir %s/%s",
- platform_file_path, sdkroot_path.c_str(),
- paths_to_try[i]);
- return true;
- }
- local_file.Clear();
- }
- }
- }
- return false;
-}
-
-Error PlatformRemoteiOS::GetSymbolFile(const FileSpec &platform_file,
- const UUID *uuid_ptr,
- FileSpec &local_file) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- Error error;
- char platform_file_path[PATH_MAX];
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- char resolved_path[PATH_MAX];
-
- const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
- if (os_version_dir) {
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
- platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists()) {
- if (log) {
- log->Printf("Found a copy of %s in the DeviceSupport dir %s",
- platform_file_path, os_version_dir);
- }
- return error;
- }
-
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
- os_version_dir, platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists()) {
- if (log) {
- log->Printf(
- "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
- platform_file_path, os_version_dir);
- }
- return error;
- }
- ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
- os_version_dir, platform_file_path);
-
- local_file.SetFile(resolved_path, true);
- if (local_file.Exists()) {
- if (log) {
- log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
- platform_file_path, os_version_dir);
- }
- return error;
- }
- }
- local_file = platform_file;
- if (local_file.Exists())
- return error;
-
- error.SetErrorStringWithFormat(
- "unable to locate a platform file for '%s' in platform '%s'",
- platform_file_path, GetPluginName().GetCString());
- } else {
- error.SetErrorString("invalid platform file argument");
- }
- return error;
-}
-
-Error PlatformRemoteiOS::GetSharedModule(
- const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) {
- // For iOS, the SDK files are all cached locally on the host
- // system. So first we ask for the file in the cached SDK,
- // then we attempt to get a shared module for the right architecture
- // with the right UUID.
- const FileSpec &platform_file = module_spec.GetFileSpec();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
-
- Error error;
- char platform_file_path[PATH_MAX];
-
- if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
- ModuleSpec platform_module_spec(module_spec);
-
- UpdateSDKDirectoryInfosIfNeeded();
-
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
-
- // If we are connected we migth be able to correctly deduce the SDK
- // directory
- // using the OS build.
- const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
- if (connected_sdk_idx < num_sdk_infos) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[connected_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, connected_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, NULL);
- if (module_sp) {
- m_last_module_sdk_idx = connected_sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
-
- // Try the last SDK index if it is set as most files from an SDK
- // will tend to be valid in that same SDK.
- if (m_last_module_sdk_idx < num_sdk_infos) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[m_last_module_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, NULL);
- if (module_sp) {
- error.Clear();
- return error;
- }
- }
- }
-
- // First try for an exact match of major, minor and update:
- // If a particalar SDK version was specified via --version or --build, look
- // for a match on disk.
- const SDKDirectoryInfo *current_sdk_info =
- GetSDKDirectoryForCurrentOSVersion();
- const uint32_t current_sdk_idx =
- GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
- if (current_sdk_idx < num_sdk_infos &&
- current_sdk_idx != m_last_module_sdk_idx) {
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[current_sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, current_sdk_idx,
- platform_module_spec.GetFileSpec())) {
- module_sp.reset();
- error = ResolveExecutable(platform_module_spec, module_sp, NULL);
- if (module_sp) {
- m_last_module_sdk_idx = current_sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
-
- // Second try all SDKs that were found.
- for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
- if (m_last_module_sdk_idx == sdk_idx) {
- // Skip the last module SDK index if we already searched
- // it above
- continue;
- }
- LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
- m_sdk_directory_infos[sdk_idx].directory);
- if (GetFileInSDK(platform_file_path, sdk_idx,
- platform_module_spec.GetFileSpec())) {
- // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
-
- error = ResolveExecutable(platform_module_spec, module_sp, NULL);
- if (module_sp) {
- // Remember the index of the last SDK that we found a file
- // in in case the wrong SDK was selected.
- m_last_module_sdk_idx = sdk_idx;
- error.Clear();
- return error;
- }
- }
- }
- }
- // Not the module we are looking for... Nothing to see here...
- module_sp.reset();
-
- // This may not be an SDK-related module. Try whether we can bring in the
- // thing to our local cache.
- error = GetSharedModuleWithLocalCache(module_spec, module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr, did_create_ptr);
- if (error.Success())
- return error;
-
- // See if the file is present in any of the module_search_paths_ptr
- // directories.
- if (!module_sp && module_search_paths_ptr && platform_file) {
- // create a vector of all the file / directory names in platform_file
- // e.g. this might be
- // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
- //
- // We'll need to look in the module_search_paths_ptr directories for
- // both "UIFoundation" and "UIFoundation.framework" -- most likely the
- // latter will be the one we find there.
-
- FileSpec platform_pull_apart(platform_file);
- std::vector<std::string> path_parts;
- ConstString unix_root_dir("/");
- while (true) {
- ConstString part = platform_pull_apart.GetLastPathComponent();
- platform_pull_apart.RemoveLastPathComponent();
- if (part.IsEmpty() || part == unix_root_dir)
- break;
- path_parts.push_back(part.AsCString());
- }
- const size_t path_parts_size = path_parts.size();
-
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i = 0; i < num_module_search_paths; ++i) {
- LLDB_LOGV(log, "searching for binary in search-path {0}",
- module_search_paths_ptr->GetFileSpecAtIndex(i));
- // Create a new FileSpec with this module_search_paths_ptr
- // plus just the filename ("UIFoundation"), then the parent
- // dir plus filename ("UIFoundation.framework/UIFoundation")
- // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
-
- for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
- FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
-
- // Add the components backwards. For
- // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
- // path_parts is
- // [0] UIFoundation
- // [1] UIFoundation.framework
- // [2] PrivateFrameworks
- //
- // and if 'j' is 2, we want to append path_parts[1] and then
- // path_parts[0], aka
- // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
- // path.
-
- for (int k = j; k >= 0; --k) {
- path_to_try.AppendPathComponent(path_parts[k]);
- }
-
- if (path_to_try.Exists()) {
- ModuleSpec new_module_spec(module_spec);
- new_module_spec.GetFileSpec() = path_to_try;
- Error new_error(Platform::GetSharedModule(
- new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp) {
- module_sp->SetPlatformFileSpec(path_to_try);
- return new_error;
- }
- }
- }
- }
- }
-
- const bool always_create = false;
- error = ModuleList::GetSharedModule(
- module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
- did_create_ptr, always_create);
-
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
-
- return error;
-}
+ : PlatformRemoteDarwinDevice() {}
bool PlatformRemoteiOS::GetSupportedArchitectureAtIndex(uint32_t idx,
ArchSpec &arch) {
return ARMGetSupportedArchitectureAtIndex(idx, arch);
}
-uint32_t PlatformRemoteiOS::GetConnectedSDKIndex() {
- if (IsConnected()) {
- if (m_connected_module_sdk_idx == UINT32_MAX) {
- std::string build;
- if (GetRemoteOSBuildString(build)) {
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- for (uint32_t i = 0; i < num_sdk_infos; ++i) {
- const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
- if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
- build.c_str())) {
- m_connected_module_sdk_idx = i;
- }
- }
- }
- }
- } else {
- m_connected_module_sdk_idx = UINT32_MAX;
- }
- return m_connected_module_sdk_idx;
-}
-uint32_t PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo(
- const SDKDirectoryInfo *sdk_info) {
- if (sdk_info == NULL) {
- return UINT32_MAX;
- }
+void PlatformRemoteiOS::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
+{
+ dirnames.clear();
+ dirnames.push_back("iOS DeviceSupport");
+}
- return sdk_info - &m_sdk_directory_infos[0];
+std::string PlatformRemoteiOS::GetPlatformName ()
+{
+ return "iPhoneOS.platform";
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
index ccdce9874762..975f50b421f1 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
@@ -16,16 +16,16 @@
// Other libraries and framework includes
// Project includes
-#include "PlatformDarwin.h"
+#include "PlatformRemoteDarwinDevice.h"
#include "lldb/Utility/FileSpec.h"
#include "llvm/Support/FileSystem.h"
-class PlatformRemoteiOS : public PlatformDarwin {
+class PlatformRemoteiOS : public PlatformRemoteDarwinDevice {
public:
PlatformRemoteiOS();
- ~PlatformRemoteiOS() override;
+ ~PlatformRemoteiOS() override = default;
//------------------------------------------------------------
// Class Functions
@@ -42,6 +42,12 @@ public:
static const char *GetDescriptionStatic();
//------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+
+ const char *GetDescription() override { return GetDescriptionStatic(); }
+
+ //------------------------------------------------------------
// lldb_private::PluginInterface functions
//------------------------------------------------------------
lldb_private::ConstString GetPluginName() override {
@@ -50,89 +56,18 @@ public:
uint32_t GetPluginVersion() override { return 1; }
- //------------------------------------------------------------
- // lldb_private::Platform functions
- //------------------------------------------------------------
- lldb_private::Error ResolveExecutable(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
- const char *GetDescription() override { return GetDescriptionStatic(); }
-
- void GetStatus(lldb_private::Stream &strm) override;
-
- virtual lldb_private::Error
- GetSymbolFile(const lldb_private::FileSpec &platform_file,
- const lldb_private::UUID *uuid_ptr,
- lldb_private::FileSpec &local_file);
-
- lldb_private::Error
- GetSharedModule(const lldb_private::ModuleSpec &module_spec,
- lldb_private::Process *process, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr) override;
-
bool GetSupportedArchitectureAtIndex(uint32_t idx,
lldb_private::ArchSpec &arch) override;
- void
- AddClangModuleCompilationOptions(lldb_private::Target *target,
- std::vector<std::string> &options) override {
- return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
- target, options, PlatformDarwin::SDKType::iPhoneOS);
- }
-
protected:
- struct SDKDirectoryInfo {
- SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
- lldb_private::FileSpec directory;
- lldb_private::ConstString build;
- uint32_t version_major;
- uint32_t version_minor;
- uint32_t version_update;
- bool user_cached;
- };
-
- typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
-
- std::mutex m_sdk_dir_mutex;
- SDKDirectoryInfoCollection m_sdk_directory_infos;
- std::string m_device_support_directory;
- std::string m_device_support_directory_for_os_version;
- std::string m_build_update;
- uint32_t m_last_module_sdk_idx;
- uint32_t m_connected_module_sdk_idx;
-
- bool UpdateSDKDirectoryInfosIfNeeded();
-
- const char *GetDeviceSupportDirectory();
-
- const char *GetDeviceSupportDirectoryForOSVersion();
- const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
-
- const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
-
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetContainedFilesIntoVectorOfStringsCallback(
- void *baton, llvm::sys::fs::file_type ft,
- const lldb_private::FileSpec &file_spec);
-
- uint32_t FindFileInAllSDKs(const char *platform_file_path,
- lldb_private::FileSpecList &file_list);
-
- bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
- lldb_private::FileSpec &local_file);
-
- uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
- lldb_private::FileSpecList &file_list);
+ //------------------------------------------------------------
+ // lldb_private::PlatformRemoteDarwinDevice functions
+ //------------------------------------------------------------
- uint32_t GetConnectedSDKIndex();
+ void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
- // Get index of SDK in SDKDirectoryInfoCollection by its pointer and return
- // UINT32_MAX if that SDK not found.
- uint32_t GetSDKIndexBySDKDirectoryInfo(const SDKDirectoryInfo *sdk_info);
+ std::string GetPlatformName () override;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformRemoteiOS);
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 298faa48e1c3..347c12943bd5 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -224,36 +224,83 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
// Get details on the signal raised.
- if (siginfo_err.Success()) {
- switch (info.psi_siginfo.si_code) {
- case TRAP_BRKPT:
+ if (siginfo_err.Fail()) {
+ return;
+ }
+
+ switch (info.psi_siginfo.si_code) {
+ case TRAP_BRKPT:
+ for (const auto &thread_sp : m_threads) {
+ static_pointer_cast<NativeThreadNetBSD>(thread_sp)
+ ->SetStoppedByBreakpoint();
+ FixupBreakpointPCAsNeeded(
+ *static_pointer_cast<NativeThreadNetBSD>(thread_sp));
+ }
+ SetState(StateType::eStateStopped, true);
+ break;
+ case TRAP_TRACE:
+ for (const auto &thread_sp : m_threads) {
+ static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByTrace();
+ }
+ SetState(StateType::eStateStopped, true);
+ break;
+ case TRAP_EXEC: {
+ Error error = ReinitializeThreads();
+ if (error.Fail()) {
+ SetState(StateType::eStateInvalid);
+ return;
+ }
+
+ // Let our delegate know we have just exec'd.
+ NotifyDidExec();
+
+ for (const auto &thread_sp : m_threads) {
+ static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByExec();
+ }
+ SetState(StateType::eStateStopped, true);
+ } break;
+ case TRAP_DBREG: {
+ // If a watchpoint was hit, report it
+ uint32_t wp_index;
+ Error error =
+ static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])
+ ->GetRegisterContext()
+ ->GetWatchpointHitIndex(wp_index,
+ (uintptr_t)info.psi_siginfo.si_addr);
+ if (error.Fail())
+ LLDB_LOG(log,
+ "received error while checking for watchpoint hits, pid = "
+ "{0}, LWP = {1}, error = {2}",
+ GetID(), info.psi_lwpid, error);
+ if (wp_index != LLDB_INVALID_INDEX32) {
for (const auto &thread_sp : m_threads) {
static_pointer_cast<NativeThreadNetBSD>(thread_sp)
- ->SetStoppedByBreakpoint();
- FixupBreakpointPCAsNeeded(
- *static_pointer_cast<NativeThreadNetBSD>(thread_sp));
+ ->SetStoppedByWatchpoint(wp_index);
}
SetState(StateType::eStateStopped, true);
break;
- case TRAP_TRACE:
+ }
+
+ // If a breakpoint was hit, report it
+ uint32_t bp_index;
+ error = static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])
+ ->GetRegisterContext()
+ ->GetHardwareBreakHitIndex(bp_index,
+ (uintptr_t)info.psi_siginfo.si_addr);
+ if (error.Fail())
+ LLDB_LOG(log,
+ "received error while checking for hardware "
+ "breakpoint hits, pid = {0}, LWP = {1}, error = {2}",
+ GetID(), info.psi_lwpid, error);
+ if (bp_index != LLDB_INVALID_INDEX32) {
for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByTrace();
+ static_pointer_cast<NativeThreadNetBSD>(thread_sp)
+ ->SetStoppedByBreakpoint();
}
SetState(StateType::eStateStopped, true);
break;
- case TRAP_EXEC: {
- Error error = ReinitializeThreads();
- if (error.Fail()) {
- SetState(StateType::eStateInvalid);
- return;
- }
-
- // Let our delegate know we have just exec'd.
- NotifyDidExec();
-
- SetState(StateType::eStateStopped, true);
- } break;
}
+ } break;
}
}
@@ -328,8 +375,8 @@ Error NativeProcessNetBSD::FixupBreakpointPCAsNeeded(
return error;
} else
LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
- // First try probing for a breakpoint at a software breakpoint location: PC -
- // breakpoint size.
+ // First try probing for a breakpoint at a software breakpoint location: PC
+ // - breakpoint size.
const lldb::addr_t initial_pc_addr =
context_sp->GetPCfromBreakpointLocation();
lldb::addr_t breakpoint_addr = initial_pc_addr;
@@ -439,7 +486,7 @@ Error NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
llvm_unreachable("Unexpected state");
default:
- return Error("NativeProcessLinux::%s (): unexpected state %s specified "
+ return Error("NativeProcessNetBSD::%s (): unexpected state %s specified "
"for pid %" PRIu64 ", tid %" PRIu64,
__FUNCTION__, StateAsCString(action->state), GetID(),
thread_sp->GetID());
@@ -540,8 +587,8 @@ Error NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
"descending memory map entries detected, unexpected");
prev_base_address = proc_entry_info.GetRange().GetRangeBase();
UNUSED_IF_ASSERT_DISABLED(prev_base_address);
- // If the target address comes before this entry, indicate distance to next
- // region.
+ // If the target address comes before this entry, indicate distance to
+ // next region.
if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
range_info.GetRange().SetRangeBase(load_addr);
range_info.GetRange().SetByteSize(
@@ -561,9 +608,8 @@ Error NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
}
// If we made it here, we didn't find an entry that contained the given
// address. Return the
- // load_addr as start and the amount of bytes betwwen load address and the end
- // of the memory as
- // size.
+ // load_addr as start and the amount of bytes betwwen load address and the
+ // end of the memory as size.
range_info.GetRange().SetRangeBase(load_addr);
range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
@@ -722,8 +768,8 @@ Error NativeProcessNetBSD::LaunchInferior(MainLoop &mainloop,
LLDB_LOG(log, "waitpid for inferior failed with %s", error);
// Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now,
- // using eStateInvalid.
+ // FIXME this could really use a new state - eStateLaunchFailure. For
+ // now, using eStateInvalid.
SetState(StateType::eStateInvalid);
return error;
@@ -766,6 +812,11 @@ Error NativeProcessNetBSD::LaunchInferior(MainLoop &mainloop,
return error;
}
+ for (const auto &thread_sp : m_threads) {
+ static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
+ SIGSTOP);
+ }
+
/* Set process stopped */
SetState(StateType::eStateStopped);
@@ -894,6 +945,11 @@ NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
return -1;
}
+ for (const auto &thread_sp : m_threads) {
+ static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
+ SIGSTOP);
+ }
+
// Let our process instance know the thread has stopped.
SetState(StateType::eStateStopped);
@@ -1007,7 +1063,6 @@ Error NativeProcessNetBSD::ReinitializeThreads() {
// Reinitialize from scratch threads and register them in process
while (info.pl_lwpid != 0) {
NativeThreadNetBSDSP thread_sp = AddThread(info.pl_lwpid);
- thread_sp->SetStoppedByExec();
error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info));
if (error.Fail()) {
return error;
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
index 1bb6324c97fe..cd47deac73ad 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
@@ -57,6 +57,22 @@ Error NativeRegisterContextNetBSD::WriteFPR() {
return DoWriteFPR(buf);
}
+Error NativeRegisterContextNetBSD::ReadDBR() {
+ void *buf = GetDBRBuffer();
+ if (!buf)
+ return Error("DBR buffer is NULL");
+
+ return DoReadDBR(buf);
+}
+
+Error NativeRegisterContextNetBSD::WriteDBR() {
+ void *buf = GetDBRBuffer();
+ if (!buf)
+ return Error("DBR buffer is NULL");
+
+ return DoWriteDBR(buf);
+}
+
Error NativeRegisterContextNetBSD::DoReadGPR(void *buf) {
return NativeProcessNetBSD::PtraceWrapper(PT_GETREGS, GetProcessPid(), buf,
m_thread.GetID());
@@ -77,6 +93,16 @@ Error NativeRegisterContextNetBSD::DoWriteFPR(void *buf) {
m_thread.GetID());
}
+Error NativeRegisterContextNetBSD::DoReadDBR(void *buf) {
+ return NativeProcessNetBSD::PtraceWrapper(PT_GETDBREGS, GetProcessPid(), buf,
+ m_thread.GetID());
+}
+
+Error NativeRegisterContextNetBSD::DoWriteDBR(void *buf) {
+ return NativeProcessNetBSD::PtraceWrapper(PT_SETDBREGS, GetProcessPid(), buf,
+ m_thread.GetID());
+}
+
NativeProcessNetBSD &NativeRegisterContextNetBSD::GetProcess() {
auto process_sp =
std::static_pointer_cast<NativeProcessNetBSD>(m_thread.GetProcess());
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
index 5ff59bc87c98..d820baac3afa 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
@@ -41,6 +41,9 @@ protected:
virtual Error ReadFPR();
virtual Error WriteFPR();
+ virtual Error ReadDBR();
+ virtual Error WriteDBR();
+
virtual void *GetGPRBuffer() { return nullptr; }
virtual size_t GetGPRSize() {
return GetRegisterInfoInterface().GetGPRSize();
@@ -49,12 +52,18 @@ protected:
virtual void *GetFPRBuffer() { return nullptr; }
virtual size_t GetFPRSize() { return 0; }
+ virtual void *GetDBRBuffer() { return nullptr; }
+ virtual size_t GetDBRSize() { return 0; }
+
virtual Error DoReadGPR(void *buf);
virtual Error DoWriteGPR(void *buf);
virtual Error DoReadFPR(void *buf);
virtual Error DoWriteFPR(void *buf);
+ virtual Error DoReadDBR(void *buf);
+ virtual Error DoWriteDBR(void *buf);
+
virtual NativeProcessNetBSD &GetProcess();
virtual ::pid_t GetProcessPid();
};
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index 76e64ac48d66..dc37be7b934b 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -19,7 +19,15 @@
#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
+// clang-format off
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <x86/cpu.h>
#include <elf.h>
+#include <err.h>
+#include <stdint.h>
+#include <stdlib.h>
+// clang-format on
using namespace lldb_private;
using namespace lldb_private::process_netbsd;
@@ -86,6 +94,57 @@ static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize())
+const int fpu_present = []() -> int {
+ int mib[2];
+ int error;
+ size_t len;
+ int val;
+
+ len = sizeof(val);
+ mib[0] = CTL_MACHDEP;
+ mib[1] = CPU_FPU_PRESENT;
+
+ error = sysctl(mib, __arraycount(mib), &val, &len, NULL, 0);
+ if (error)
+ errx(EXIT_FAILURE, "sysctl");
+
+ return val;
+}();
+
+const int osfxsr = []() -> int {
+ int mib[2];
+ int error;
+ size_t len;
+ int val;
+
+ len = sizeof(val);
+ mib[0] = CTL_MACHDEP;
+ mib[1] = CPU_OSFXSR;
+
+ error = sysctl(mib, __arraycount(mib), &val, &len, NULL, 0);
+ if (error)
+ errx(EXIT_FAILURE, "sysctl");
+
+ return val;
+}();
+
+const int fpu_save = []() -> int {
+ int mib[2];
+ int error;
+ size_t len;
+ int val;
+
+ len = sizeof(val);
+ mib[0] = CTL_MACHDEP;
+ mib[1] = CPU_FPU_SAVE;
+
+ error = sysctl(mib, __arraycount(mib), &val, &len, NULL, 0);
+ if (error)
+ errx(EXIT_FAILURE, "sysctl");
+
+ return val;
+}();
+
} // namespace
NativeRegisterContextNetBSD *
@@ -114,7 +173,7 @@ NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64(
uint32_t concrete_frame_idx)
: NativeRegisterContextNetBSD(native_thread, concrete_frame_idx,
CreateRegisterInfoInterface(target_arch)),
- m_gpr_x86_64() {}
+ m_gpr_x86_64(), m_fpr_x86_64(), m_dbr_x86_64() {}
// CONSIDER after local and llgs debugging are merged, register set support can
// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
@@ -143,8 +202,18 @@ NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const {
int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
int reg_num) const {
- if (reg_num < lldb_fctrl_x86_64)
+ if (reg_num <= k_last_gpr_x86_64)
return GPRegSet;
+ else if (reg_num <= k_last_fpr_x86_64)
+ return (fpu_present == 1 && osfxsr == 1 && fpu_save >= 1) ? FPRegSet : -1;
+ else if (reg_num <= k_last_avx_x86_64)
+ return -1; // AVX
+ else if (reg_num <= k_last_mpxr_x86_64)
+ return -1; // MPXR
+ else if (reg_num <= k_last_mpxc_x86_64)
+ return -1; // MPXC
+ else if (reg_num <= lldb_dr7_x86_64)
+ return DBRegSet; // DBR
else
return -1;
}
@@ -157,6 +226,9 @@ int NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) {
case FPRegSet:
ReadFPR();
return 0;
+ case DBRegSet:
+ ReadDBR();
+ return 0;
default:
break;
}
@@ -170,6 +242,9 @@ int NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) {
case FPRegSet:
WriteFPR();
return 0;
+ case DBRegSet:
+ WriteDBR();
+ return 0;
default:
break;
}
@@ -285,6 +360,87 @@ Error NativeRegisterContextNetBSD_x86_64::ReadRegister(
case lldb_es_x86_64:
reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_ES];
break;
+ case lldb_fctrl_x86_64:
+ reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_cw;
+ break;
+ case lldb_fstat_x86_64:
+ reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_sw;
+ break;
+ case lldb_ftag_x86_64:
+ reg_value = (uint8_t)m_fpr_x86_64.fxstate.fx_tw;
+ break;
+ case lldb_fop_x86_64:
+ reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_opcode;
+ break;
+ case lldb_fiseg_x86_64:
+ reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_ip.fa_64;
+ break;
+ case lldb_fioff_x86_64:
+ reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_ip.fa_32.fa_off;
+ break;
+ case lldb_foseg_x86_64:
+ reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_dp.fa_64;
+ break;
+ case lldb_fooff_x86_64:
+ reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_dp.fa_32.fa_off;
+ break;
+ case lldb_mxcsr_x86_64:
+ reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr;
+ break;
+ case lldb_mxcsrmask_x86_64:
+ reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr_mask;
+ break;
+ case lldb_st0_x86_64:
+ case lldb_st1_x86_64:
+ case lldb_st2_x86_64:
+ case lldb_st3_x86_64:
+ case lldb_st4_x86_64:
+ case lldb_st5_x86_64:
+ case lldb_st6_x86_64:
+ case lldb_st7_x86_64:
+ reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_mm0_x86_64:
+ case lldb_mm1_x86_64:
+ case lldb_mm2_x86_64:
+ case lldb_mm3_x86_64:
+ case lldb_mm4_x86_64:
+ case lldb_mm5_x86_64:
+ case lldb_mm6_x86_64:
+ case lldb_mm7_x86_64:
+ reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_mm0_x86_64],
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm0_x86_64:
+ case lldb_xmm1_x86_64:
+ case lldb_xmm2_x86_64:
+ case lldb_xmm3_x86_64:
+ case lldb_xmm4_x86_64:
+ case lldb_xmm5_x86_64:
+ case lldb_xmm6_x86_64:
+ case lldb_xmm7_x86_64:
+ case lldb_xmm8_x86_64:
+ case lldb_xmm9_x86_64:
+ case lldb_xmm10_x86_64:
+ case lldb_xmm11_x86_64:
+ case lldb_xmm12_x86_64:
+ case lldb_xmm13_x86_64:
+ case lldb_xmm14_x86_64:
+ case lldb_xmm15_x86_64:
+ reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_dr0_x86_64:
+ case lldb_dr1_x86_64:
+ case lldb_dr2_x86_64:
+ case lldb_dr3_x86_64:
+ case lldb_dr4_x86_64:
+ case lldb_dr5_x86_64:
+ case lldb_dr6_x86_64:
+ case lldb_dr7_x86_64:
+ reg_value = (uint64_t)m_dbr_x86_64.dr[reg - lldb_dr0_x86_64];
+ break;
}
return error;
@@ -400,6 +556,87 @@ Error NativeRegisterContextNetBSD_x86_64::WriteRegister(
case lldb_es_x86_64:
m_gpr_x86_64.regs[_REG_ES] = reg_value.GetAsUInt64();
break;
+ case lldb_fctrl_x86_64:
+ m_fpr_x86_64.fxstate.fx_cw = reg_value.GetAsUInt16();
+ break;
+ case lldb_fstat_x86_64:
+ m_fpr_x86_64.fxstate.fx_sw = reg_value.GetAsUInt16();
+ break;
+ case lldb_ftag_x86_64:
+ m_fpr_x86_64.fxstate.fx_tw = reg_value.GetAsUInt8();
+ break;
+ case lldb_fop_x86_64:
+ m_fpr_x86_64.fxstate.fx_opcode = reg_value.GetAsUInt16();
+ break;
+ case lldb_fiseg_x86_64:
+ m_fpr_x86_64.fxstate.fx_ip.fa_64 = reg_value.GetAsUInt64();
+ break;
+ case lldb_fioff_x86_64:
+ m_fpr_x86_64.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
+ break;
+ case lldb_foseg_x86_64:
+ m_fpr_x86_64.fxstate.fx_dp.fa_64 = reg_value.GetAsUInt64();
+ break;
+ case lldb_fooff_x86_64:
+ m_fpr_x86_64.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
+ break;
+ case lldb_mxcsr_x86_64:
+ m_fpr_x86_64.fxstate.fx_mxcsr = reg_value.GetAsUInt32();
+ break;
+ case lldb_mxcsrmask_x86_64:
+ m_fpr_x86_64.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32();
+ break;
+ case lldb_st0_x86_64:
+ case lldb_st1_x86_64:
+ case lldb_st2_x86_64:
+ case lldb_st3_x86_64:
+ case lldb_st4_x86_64:
+ case lldb_st5_x86_64:
+ case lldb_st6_x86_64:
+ case lldb_st7_x86_64:
+ ::memcpy(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ break;
+ case lldb_mm0_x86_64:
+ case lldb_mm1_x86_64:
+ case lldb_mm2_x86_64:
+ case lldb_mm3_x86_64:
+ case lldb_mm4_x86_64:
+ case lldb_mm5_x86_64:
+ case lldb_mm6_x86_64:
+ case lldb_mm7_x86_64:
+ ::memcpy(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_mm0_x86_64],
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ break;
+ case lldb_xmm0_x86_64:
+ case lldb_xmm1_x86_64:
+ case lldb_xmm2_x86_64:
+ case lldb_xmm3_x86_64:
+ case lldb_xmm4_x86_64:
+ case lldb_xmm5_x86_64:
+ case lldb_xmm6_x86_64:
+ case lldb_xmm7_x86_64:
+ case lldb_xmm8_x86_64:
+ case lldb_xmm9_x86_64:
+ case lldb_xmm10_x86_64:
+ case lldb_xmm11_x86_64:
+ case lldb_xmm12_x86_64:
+ case lldb_xmm13_x86_64:
+ case lldb_xmm14_x86_64:
+ case lldb_xmm15_x86_64:
+ ::memcpy(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ break;
+ case lldb_dr0_x86_64:
+ case lldb_dr1_x86_64:
+ case lldb_dr2_x86_64:
+ case lldb_dr3_x86_64:
+ case lldb_dr4_x86_64:
+ case lldb_dr5_x86_64:
+ case lldb_dr6_x86_64:
+ case lldb_dr7_x86_64:
+ m_dbr_x86_64.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
+ break;
}
if (WriteRegisterSet(set) != 0)
@@ -480,4 +717,223 @@ Error NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
return error;
}
+Error NativeRegisterContextNetBSD_x86_64::IsWatchpointHit(uint32_t wp_index,
+ bool &is_hit) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
+
+ RegisterValue reg_value;
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr6_x86_64);
+ Error error = ReadRegister(reg_info, reg_value);
+ if (error.Fail()) {
+ is_hit = false;
+ return error;
+ }
+
+ uint64_t status_bits = reg_value.GetAsUInt64();
+
+ is_hit = status_bits & (1 << wp_index);
+
+ return error;
+}
+
+Error NativeRegisterContextNetBSD_x86_64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+ bool is_hit;
+ Error error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ return error;
+ } else if (is_hit) {
+ return error;
+ }
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
+}
+
+Error NativeRegisterContextNetBSD_x86_64::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
+
+ RegisterValue reg_value;
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ Error error = ReadRegister(reg_info, reg_value);
+ if (error.Fail()) {
+ is_vacant = false;
+ return error;
+ }
+
+ uint64_t control_bits = reg_value.GetAsUInt64();
+
+ is_vacant = !(control_bits & (1 << (2 * wp_index)));
+
+ return error;
+}
+
+Error NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
+
+ // Read only watchpoints aren't supported on x86_64. Fall back to read/write
+ // waitchpoints instead.
+ // TODO: Add logic to detect when a write happens and ignore that watchpoint
+ // hit.
+ if (watch_flags == 0x2)
+ watch_flags = 0x3;
+
+ if (watch_flags != 0x1 && watch_flags != 0x3)
+ return Error("Invalid read/write bits for watchpoint");
+
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return Error("Invalid size for watchpoint");
+
+ bool is_vacant;
+ Error error = IsWatchpointVacant(wp_index, is_vacant);
+ if (error.Fail())
+ return error;
+ if (!is_vacant)
+ return Error("Watchpoint index not vacant");
+
+ RegisterValue reg_value;
+ const RegisterInfo *const reg_info_dr7 =
+ GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ error = ReadRegister(reg_info_dr7, reg_value);
+ if (error.Fail())
+ return error;
+
+ // for watchpoints 0, 1, 2, or 3, respectively,
+ // set bits 1, 3, 5, or 7
+ uint64_t enable_bit = 1 << (2 * wp_index);
+
+ // set bits 16-17, 20-21, 24-25, or 28-29
+ // with 0b01 for write, and 0b11 for read/write
+ uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
+
+ // set bits 18-19, 22-23, 26-27, or 30-31
+ // with 0b00, 0b01, 0b10, or 0b11
+ // for 1, 2, 8 (if supported), or 4 bytes, respectively
+ uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
+
+ uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
+
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+
+ control_bits |= enable_bit | rw_bits | size_bits;
+
+ const RegisterInfo *const reg_info_drN =
+ GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index);
+ error = WriteRegister(reg_info_drN, RegisterValue(addr));
+ if (error.Fail())
+ return error;
+
+ error = WriteRegister(reg_info_dr7, RegisterValue(control_bits));
+ if (error.Fail())
+ return error;
+
+ error.Clear();
+ return error;
+}
+
+bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return false;
+
+ RegisterValue reg_value;
+
+ // for watchpoints 0, 1, 2, or 3, respectively,
+ // clear bits 0, 1, 2, or 3 of the debug status register (DR6)
+ const RegisterInfo *const reg_info_dr6 =
+ GetRegisterInfoAtIndex(lldb_dr6_x86_64);
+ Error error = ReadRegister(reg_info_dr6, reg_value);
+ if (error.Fail())
+ return false;
+ uint64_t bit_mask = 1 << wp_index;
+ uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ error = WriteRegister(reg_info_dr6, RegisterValue(status_bits));
+ if (error.Fail())
+ return false;
+
+ // for watchpoints 0, 1, 2, or 3, respectively,
+ // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31}
+ // of the debug control register (DR7)
+ const RegisterInfo *const reg_info_dr7 =
+ GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ error = ReadRegister(reg_info_dr7, reg_value);
+ if (error.Fail())
+ return false;
+ bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ return WriteRegister(reg_info_dr7, RegisterValue(control_bits)).Success();
+}
+
+Error NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() {
+ RegisterValue reg_value;
+
+ // clear bits {0-4} of the debug status register (DR6)
+ const RegisterInfo *const reg_info_dr6 =
+ GetRegisterInfoAtIndex(lldb_dr6_x86_64);
+ Error error = ReadRegister(reg_info_dr6, reg_value);
+ if (error.Fail())
+ return error;
+ uint64_t bit_mask = 0xF;
+ uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ error = WriteRegister(reg_info_dr6, RegisterValue(status_bits));
+ if (error.Fail())
+ return error;
+
+ // clear bits {0-7,16-31} of the debug control register (DR7)
+ const RegisterInfo *const reg_info_dr7 =
+ GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ error = ReadRegister(reg_info_dr7, reg_value);
+ if (error.Fail())
+ return error;
+ bit_mask = 0xFF | (0xFFFF << 16);
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ return WriteRegister(reg_info_dr7, RegisterValue(control_bits));
+}
+
+uint32_t NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
+ bool is_vacant;
+ Error error = IsWatchpointVacant(wp_index, is_vacant);
+ if (is_vacant) {
+ error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
+ if (error.Success())
+ return wp_index;
+ }
+ if (error.Fail() && log) {
+ log->Printf("NativeRegisterContextNetBSD_x86_64::%s Error: %s",
+ __FUNCTION__, error.AsCString());
+ }
+ }
+ return LLDB_INVALID_INDEX32;
+}
+
+lldb::addr_t
+NativeRegisterContextNetBSD_x86_64::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
+ RegisterValue reg_value;
+ const RegisterInfo *const reg_info_drN =
+ GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index);
+ if (ReadRegister(reg_info_drN, reg_value).Fail())
+ return LLDB_INVALID_ADDRESS;
+ return reg_value.GetAsUInt64();
+}
+
+uint32_t NativeRegisterContextNetBSD_x86_64::NumSupportedHardwareWatchpoints() {
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
+}
+
#endif // defined(__x86_64__)
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
index f6f7d7f0976a..35b7cf1c2f19 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
@@ -46,17 +46,40 @@ public:
Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ Error IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
+
+ Error IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
+
+ Error ClearAllHardwareWatchpoints() override;
+
+ Error SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, uint32_t wp_index);
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
+
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
protected:
void *GetGPRBuffer() override { return &m_gpr_x86_64; }
void *GetFPRBuffer() override { return &m_fpr_x86_64; }
+ void *GetDBRBuffer() override { return &m_dbr_x86_64; }
private:
// Private member types.
- enum { GPRegSet, FPRegSet };
+ enum { GPRegSet, FPRegSet, DBRegSet };
// Private member variables.
struct reg m_gpr_x86_64;
struct fpreg m_fpr_x86_64;
+ struct dbreg m_dbr_x86_64;
int GetSetForNativeRegNum(int reg_num) const;
diff --git a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index f23621e45aad..9beb65288c2f 100644
--- a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -16,6 +16,9 @@
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/State.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+#include <sstream>
using namespace lldb;
using namespace lldb_private;
@@ -68,6 +71,23 @@ void NativeThreadNetBSD::SetStoppedByExec() {
m_stop_info.details.signal.signo = SIGTRAP;
}
+void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
+ SetStopped();
+
+ lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
+
+ std::ostringstream ostr;
+ ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
+ ostr << wp_index;
+
+ ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
+
+ m_stop_description = ostr.str();
+
+ m_stop_info.reason = StopReason::eStopReasonWatchpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
+}
+
void NativeThreadNetBSD::SetStopped() {
const StateType new_state = StateType::eStateStopped;
m_state = new_state;
@@ -142,18 +162,61 @@ NativeRegisterContextSP NativeThreadNetBSD::GetRegisterContext() {
Error NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
uint32_t watch_flags, bool hardware) {
- return Error("Unimplemented");
+ if (!hardware)
+ return Error("not implemented");
+ if (m_state == eStateLaunching)
+ return Error();
+ Error error = RemoveWatchpoint(addr);
+ if (error.Fail())
+ return error;
+ NativeRegisterContextSP reg_ctx = GetRegisterContext();
+ uint32_t wp_index = reg_ctx->SetHardwareWatchpoint(addr, size, watch_flags);
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return Error("Setting hardware watchpoint failed.");
+ m_watchpoint_index_map.insert({addr, wp_index});
+ return Error();
}
Error NativeThreadNetBSD::RemoveWatchpoint(lldb::addr_t addr) {
- return Error("Unimplemented");
+ auto wp = m_watchpoint_index_map.find(addr);
+ if (wp == m_watchpoint_index_map.end())
+ return Error();
+ uint32_t wp_index = wp->second;
+ m_watchpoint_index_map.erase(wp);
+ if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
+ return Error();
+ return Error("Clearing hardware watchpoint failed.");
}
Error NativeThreadNetBSD::SetHardwareBreakpoint(lldb::addr_t addr,
size_t size) {
- return Error("Unimplemented");
+ if (m_state == eStateLaunching)
+ return Error();
+
+ Error error = RemoveHardwareBreakpoint(addr);
+ if (error.Fail())
+ return error;
+
+ NativeRegisterContextSP reg_ctx = GetRegisterContext();
+ uint32_t bp_index = reg_ctx->SetHardwareBreakpoint(addr, size);
+
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return Error("Setting hardware breakpoint failed.");
+
+ m_hw_break_index_map.insert({addr, bp_index});
+ return Error();
}
Error NativeThreadNetBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
- return Error("Unimplemented");
+ auto bp = m_hw_break_index_map.find(addr);
+ if (bp == m_hw_break_index_map.end())
+ return Error();
+
+ uint32_t bp_index = bp->second;
+ if (GetRegisterContext()->ClearHardwareBreakpoint(bp_index)) {
+ m_hw_break_index_map.erase(bp);
+ return Error();
+ }
+
+ return Error("Clearing hardware breakpoint failed.");
}
diff --git a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
index 85fff5d5653f..96d7fd0ce03b 100644
--- a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
@@ -12,6 +12,9 @@
#include "lldb/Host/common/NativeThreadProtocol.h"
+#include <map>
+#include <string>
+
namespace lldb_private {
namespace process_netbsd {
@@ -53,6 +56,7 @@ private:
void SetStoppedByBreakpoint();
void SetStoppedByTrace();
void SetStoppedByExec();
+ void SetStoppedByWatchpoint(uint32_t wp_index);
void SetStopped();
void SetRunning();
void SetStepping();
@@ -64,6 +68,9 @@ private:
ThreadStopInfo m_stop_info;
NativeRegisterContextSP m_reg_context_sp;
std::string m_stop_description;
+ using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
+ WatchpointIndexMap m_watchpoint_index_map;
+ WatchpointIndexMap m_hw_break_index_map;
};
typedef std::shared_ptr<NativeThreadNetBSD> NativeThreadNetBSDSP;
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
index 207c69313282..6a55947ba5c2 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
@@ -55,9 +55,10 @@ RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(
m_registers_count[i] = reg_set_ptr->num_registers;
}
- assert(m_num_registers == m_registers_count[gpr_registers_count] +
- m_registers_count[fpr_registers_count] +
- m_registers_count[msa_registers_count]);
+ assert(m_num_registers ==
+ static_cast<uint32_t>(m_registers_count[gpr_registers_count] +
+ m_registers_count[fpr_registers_count] +
+ m_registers_count[msa_registers_count]));
// elf-core yet to support ReadFPR()
ProcessSP base = CalculateProcess();
diff --git a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
index 2ba8059911a0..8861ecd66806 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -148,7 +148,7 @@
DR_OFFSET(i), eEncodingUint, eFormatHex, \
{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- LLDB_INVALID_REGNUM }, \
+ lldb_##reg##i##_x86_64 }, \
nullptr, nullptr, nullptr, 0 \
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 7ef253decad6..d527b4daaab9 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -1310,12 +1310,20 @@ void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); }
GDBRemoteCommunication::ScopedTimeout::ScopedTimeout(
GDBRemoteCommunication &gdb_comm, std::chrono::seconds timeout)
- : m_gdb_comm(gdb_comm) {
- m_saved_timeout = m_gdb_comm.SetPacketTimeout(timeout);
+ : m_gdb_comm(gdb_comm), m_timeout_modified(false) {
+ auto curr_timeout = gdb_comm.GetPacketTimeout();
+ // Only update the timeout if the timeout is greater than the current
+ // timeout. If the current timeout is larger, then just use that.
+ if (curr_timeout < timeout) {
+ m_timeout_modified = true;
+ m_saved_timeout = m_gdb_comm.SetPacketTimeout(timeout);
+ }
}
GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout() {
- m_gdb_comm.SetPacketTimeout(m_saved_timeout);
+ // Only restore the timeout if we set it in the constructor.
+ if (m_timeout_modified)
+ m_gdb_comm.SetPacketTimeout(m_saved_timeout);
}
// This function is called via the Communications class read thread when bytes
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 1f3fa17cfc26..b49e05e22d95 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -89,6 +89,10 @@ public:
private:
GDBRemoteCommunication &m_gdb_comm;
std::chrono::seconds m_saved_timeout;
+ // Don't ever reduce the timeout for a packet, only increase it. If the
+ // requested timeout if less than the current timeout, we don't set it
+ // and won't need to restore it.
+ bool m_timeout_modified;
};
GDBRemoteCommunication(const char *comm_name, const char *listener_name);
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 482a08322663..6ad353099bc5 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -4484,7 +4484,8 @@ ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
const clang::ObjCInterfaceType *objc_interface_type =
objc_class_type->getInterfaceType();
if (objc_interface_type &&
- GetCompleteType((lldb::opaque_compiler_type_t)objc_interface_type)) {
+ GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
+ const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
clang::ObjCInterfaceDecl *class_interface_decl =
objc_interface_type->getDecl();
if (class_interface_decl) {
@@ -4592,7 +4593,8 @@ ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
const clang::ObjCInterfaceType *objc_interface_type =
objc_class_type->getInterfaceType();
if (objc_interface_type &&
- GetCompleteType((lldb::opaque_compiler_type_t)objc_interface_type)) {
+ GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
+ const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
clang::ObjCInterfaceDecl *class_interface_decl =
objc_interface_type->getDecl();
if (class_interface_decl) {
@@ -5660,7 +5662,8 @@ uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
const clang::ObjCInterfaceType *objc_interface_type =
objc_class_type->getInterfaceType();
if (objc_interface_type &&
- GetCompleteType((lldb::opaque_compiler_type_t)objc_interface_type)) {
+ GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
+ const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
clang::ObjCInterfaceDecl *class_interface_decl =
objc_interface_type->getDecl();
if (class_interface_decl) {
@@ -5807,7 +5810,8 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
const clang::ObjCInterfaceType *objc_interface_type =
objc_class_type->getInterfaceType();
if (objc_interface_type &&
- GetCompleteType((lldb::opaque_compiler_type_t)objc_interface_type)) {
+ GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
+ const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
clang::ObjCInterfaceDecl *class_interface_decl =
objc_interface_type->getDecl();
if (class_interface_decl) {
diff --git a/source/Utility/StringLexer.cpp b/source/Utility/StringLexer.cpp
index 77484d6e43fb..d5c7fc628988 100644
--- a/source/Utility/StringLexer.cpp
+++ b/source/Utility/StringLexer.cpp
@@ -73,10 +73,6 @@ void StringLexer::PutBack(Size s) {
m_position -= s;
}
-bool StringLexer::HasAny(Character c) {
- return m_data.find(c, m_position) != std::string::npos;
-}
-
std::string StringLexer::GetUnlexed() {
return std::string(m_data, m_position);
}
diff --git a/unittests/Core/ArchSpecTest.cpp b/unittests/Core/ArchSpecTest.cpp
index 32b363652f75..8fed7adba07c 100644
--- a/unittests/Core/ArchSpecTest.cpp
+++ b/unittests/Core/ArchSpecTest.cpp
@@ -134,3 +134,22 @@ TEST(ArchSpecTest, TestSetTriple) {
AS = ArchSpec();
EXPECT_FALSE(AS.SetTriple(""));
}
+
+TEST(ArchSpecTest, MergeFrom) {
+ ArchSpec A;
+ ArchSpec B("x86_64-pc-linux");
+
+ EXPECT_FALSE(A.IsValid());
+ ASSERT_TRUE(B.IsValid());
+ EXPECT_EQ(llvm::Triple::ArchType::x86_64, B.GetTriple().getArch());
+ EXPECT_EQ(llvm::Triple::VendorType::PC, B.GetTriple().getVendor());
+ EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS());
+ EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, B.GetCore());
+
+ A.MergeFrom(B);
+ ASSERT_TRUE(A.IsValid());
+ EXPECT_EQ(llvm::Triple::ArchType::x86_64, A.GetTriple().getArch());
+ EXPECT_EQ(llvm::Triple::VendorType::PC, A.GetTriple().getVendor());
+ EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
+ EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, A.GetCore());
+}