From d44a35e87e405ae98902dc491ba70ed82f58f592 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Thu, 20 Apr 2017 21:21:28 +0000 Subject: [PATCH] Vendor import of lldb trunk r300890: https://llvm.org/svn/llvm-project/lldb/trunk@300890 --- cmake/modules/LLDBConfig.cmake | 2 + include/lldb/Core/ArchSpec.h | 1 + include/lldb/Expression/DiagnosticManager.h | 2 + include/lldb/Utility/StringLexer.h | 2 - lldb.xcodeproj/project.pbxproj | 8 + .../libcxx/atomic/TestLibCxxAtomic.py | 4 +- .../list/TestDataFormatterLibcxxList.py | 3 +- .../libcxx/set/TestDataFormatterLibcxxSet.py | 145 ++-- .../test/functionalities/frame_var/Makefile | 6 + .../functionalities/frame_var/TestFrameVar.py | 99 +++ .../test/functionalities/frame_var/main.c | 11 + .../history/TestHistoryRecall.py | 45 ++ .../postmortem/elf-core/TestLinuxCore.py | 6 - .../postmortem/elf-core/gcore/TestGCore.py | 2 - .../thread_crash/TestLinuxCoreThreads.py | 2 - .../test/lang/c/register_variables/test.c | 13 +- .../cpp/class_static/TestStaticVariables.py | 16 +- source/Commands/CommandObjectCommands.cpp | 6 +- source/Commands/CommandObjectFrame.cpp | 84 ++- source/Core/ArchSpec.cpp | 32 +- source/Core/Scalar.cpp | 2 +- source/Expression/DiagnosticManager.cpp | 9 + source/Interpreter/CommandHistory.cpp | 4 +- .../RenderScriptRuntime.cpp | 69 +- source/Plugins/Platform/MacOSX/CMakeLists.txt | 1 + .../Platform/MacOSX/PlatformDarwin.cpp | 2 + .../Platform/MacOSX/PlatformDarwinKernel.cpp | 34 +- .../Platform/MacOSX/PlatformRemoteAppleTV.cpp | 656 +--------------- .../Platform/MacOSX/PlatformRemoteAppleTV.h | 76 +- .../MacOSX/PlatformRemoteAppleWatch.cpp | 666 +--------------- .../MacOSX/PlatformRemoteAppleWatch.h | 79 +- .../MacOSX/PlatformRemoteDarwinDevice.cpp | 712 ++++++++++++++++++ .../MacOSX/PlatformRemoteDarwinDevice.h | 118 +++ .../Platform/MacOSX/PlatformRemoteiOS.cpp | 674 +---------------- .../Platform/MacOSX/PlatformRemoteiOS.h | 93 +-- .../Process/NetBSD/NativeProcessNetBSD.cpp | 123 ++- .../NetBSD/NativeRegisterContextNetBSD.cpp | 26 + .../NetBSD/NativeRegisterContextNetBSD.h | 9 + .../NativeRegisterContextNetBSD_x86_64.cpp | 460 ++++++++++- .../NativeRegisterContextNetBSD_x86_64.h | 25 +- .../Process/NetBSD/NativeThreadNetBSD.cpp | 71 +- .../Process/NetBSD/NativeThreadNetBSD.h | 7 + .../Utility/RegisterContextPOSIX_mips64.cpp | 7 +- .../Process/Utility/RegisterInfos_x86_64.h | 2 +- .../gdb-remote/GDBRemoteCommunication.cpp | 14 +- .../gdb-remote/GDBRemoteCommunication.h | 4 + source/Symbol/ClangASTContext.cpp | 12 +- source/Utility/StringLexer.cpp | 4 - unittests/Core/ArchSpecTest.cpp | 19 + 49 files changed, 2078 insertions(+), 2389 deletions(-) create mode 100644 packages/Python/lldbsuite/test/functionalities/frame_var/Makefile create mode 100644 packages/Python/lldbsuite/test/functionalities/frame_var/TestFrameVar.py create mode 100644 packages/Python/lldbsuite/test/functionalities/frame_var/main.c create mode 100644 packages/Python/lldbsuite/test/functionalities/history/TestHistoryRecall.py create mode 100644 source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp create mode 100644 source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake index 79e82fbb3fb..60af9504ee8 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 648815c2137..75c7079be08 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 d9024e649b8..83e67df2649 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 e2c31db329c..e4fc81a85e0 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 8e44b5f07dc..6bcd8619f0b 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 = ""; }; AF33B4BD1C1FA441001B28D9 /* NetBSDSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetBSDSignals.h; path = Utility/NetBSDSignals.h; sourceTree = ""; }; AF37E10917C861F20061E18E /* ProcessRunLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessRunLock.cpp; sourceTree = ""; }; + AF3A4AD01EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformRemoteDarwinDevice.cpp; sourceTree = ""; }; + AF3A4AD11EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRemoteDarwinDevice.h; sourceTree = ""; }; AF3F54AE1B3BA59C00186E73 /* CrashReason.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrashReason.cpp; sourceTree = ""; }; AF3F54AF1B3BA59C00186E73 /* CrashReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrashReason.h; sourceTree = ""; }; AF3F54B21B3BA5D500186E73 /* POSIXStopInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = POSIXStopInfo.cpp; sourceTree = ""; }; @@ -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 2b63dbb1c83..8d4132444fb 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 dd97a9ab597..bb20b0e7d98 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 be1547ea5d8..ca892812924 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 00000000000..50d4ab65a6e --- /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 00000000000..b29f94bdb05 --- /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 00000000000..da23af2ac55 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/frame_var/main.c @@ -0,0 +1,11 @@ +#include + +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 00000000000..90bd64901ee --- /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 38b55ef40c6..18c0da83260 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 # , 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 # , 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 # , 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 # , 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 # , 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 # , 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 5b398c1ccf0..5a11a52e93a 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 # , 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 # , 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 4895c051d63..7cc3c0775ce 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 # , 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 # , 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 476c32899ed..b95253ef9ee 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 +#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 10e29e9899d..0100a2727b3 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="") - @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 102010e8e6f..e39c0330b65 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 \"!\". \"!-\" will re-run " + "the command that is 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 8be9b6f9b7a..7e81f5f9414 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(); + 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(); - 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; + // 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 (!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); + 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 60ee237aa0f..7c1b399177f 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 88ad430ddba..3adf8509864 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 5ade0817b1e..ae20feb910d 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 0fa25ed806f..ca5c90692b6 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 638112b9ebd..7a9e66cf548 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 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 449db7cd061..f8d911b321f 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 7c90f87189a..02459045869 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 7116dca6591..08df0565acc 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(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(bundle_conststr, file_spec)); + } } } } diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp index 05d1bd49daf..6fdaa5997b4 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 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 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 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 &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 beae827edba..08dd231e85e 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(); @@ -42,9 +42,6 @@ public: static const char *GetDescriptionStatic(); - //------------------------------------------------------------ - // Class Methods - //------------------------------------------------------------ //------------------------------------------------------------ // lldb_private::PluginInterface functions //------------------------------------------------------------ @@ -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 &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 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(); + //------------------------------------------------------------ + // lldb_private::PlatformRemoteDarwinDevice functions + //------------------------------------------------------------ - const char *GetDeviceSupportDirectory(); + void GetDeviceSupportDirectoryNames (std::vector &dirnames) override; - 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(); + 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 139364a82b9..18692643097 100644 --- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp +++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp @@ -33,27 +33,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 //------------------------------------------------------------------ @@ -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 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 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 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 &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 d6c91140171..93be55b595f 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 &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 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(); + //------------------------------------------------------------ + // lldb_private::PlatformRemoteDarwinDevice functions + //------------------------------------------------------------ - const char *GetDeviceSupportDirectory(); + void GetDeviceSupportDirectoryNames (std::vector &dirnames) override; - 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(); + 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 00000000000..0302e7b3aaf --- /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 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 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 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 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 00000000000..55fb4f920c6 --- /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 + +// 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 &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 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 &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 9d47b2464a2..ec1109fb4b4 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 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 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 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; + +void PlatformRemoteiOS::GetDeviceSupportDirectoryNames (std::vector &dirnames) +{ + dirnames.clear(); + dirnames.push_back("iOS DeviceSupport"); } -uint32_t PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo( - const SDKDirectoryInfo *sdk_info) { - if (sdk_info == NULL) { - return UINT32_MAX; - } - - 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 ccdce987476..975f50b421f 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 @@ -41,6 +41,12 @@ public: static const char *GetDescriptionStatic(); + //------------------------------------------------------------ + // lldb_private::Platform functions + //------------------------------------------------------------ + + const char *GetDescription() override { return GetDescriptionStatic(); } + //------------------------------------------------------------ // lldb_private::PluginInterface functions //------------------------------------------------------------ @@ -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 &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 SDKDirectoryInfoCollection; + //------------------------------------------------------------ + // lldb_private::PlatformRemoteDarwinDevice functions + //------------------------------------------------------------ - 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; + void GetDeviceSupportDirectoryNames (std::vector &dirnames) override; - 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); + 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 298faa48e1c..347c12943bd 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(thread_sp) + ->SetStoppedByBreakpoint(); + FixupBreakpointPCAsNeeded( + *static_pointer_cast(thread_sp)); + } + SetState(StateType::eStateStopped, true); + break; + case TRAP_TRACE: + for (const auto &thread_sp : m_threads) { + static_pointer_cast(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(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(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(thread_sp) + ->SetStoppedByWatchpoint(wp_index); + } + SetState(StateType::eStateStopped, true); + break; + } + + // If a breakpoint was hit, report it + uint32_t bp_index; + error = static_pointer_cast(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(thread_sp) ->SetStoppedByBreakpoint(); - FixupBreakpointPCAsNeeded( - *static_pointer_cast(thread_sp)); } SetState(StateType::eStateStopped, true); break; - case TRAP_TRACE: - for (const auto &thread_sp : m_threads) { - static_pointer_cast(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(); - - 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(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(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 1bb6324c97f..cd47deac73a 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(m_thread.GetProcess()); diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h index 5ff59bc87c9..d820baac3af 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 76e64ac48d6..dc37be7b934 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 +#include +#include #include +#include +#include +#include +// 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 f6f7d7f0976..35b7cf1c2f1 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 f23621e45aa..9beb65288c2 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 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 85fff5d5653..96d7fd0ce03 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 +#include + 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; + WatchpointIndexMap m_watchpoint_index_map; + WatchpointIndexMap m_hw_break_index_map; }; typedef std::shared_ptr NativeThreadNetBSDSP; diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp index 207c6931328..6a55947ba5c 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(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 2ba8059911a..8861ecd6680 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 7ef253decad..d527b4daaab 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 1f3fa17cfc2..b49e05e22d9 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 482a0832266..6ad353099bc 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( + const_cast(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( + const_cast(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( + const_cast(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( + const_cast(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 77484d6e43f..d5c7fc62898 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 32b363652f7..8fed7adba07 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()); +}