diff options
| -rw-r--r-- | lldb/include/lldb/Host/Debug.h | 406 | ||||
| -rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 379 | ||||
| -rw-r--r-- | lldb/tools/lldb-gdbserver/CMakeLists.txt | 14 | ||||
| -rw-r--r-- | lldb/tools/lldb-gdbserver/Makefile | 23 | ||||
| -rw-r--r-- | lldb/tools/lldb-gdbserver/lldb-gdbserver.cpp | 240 |
5 files changed, 1048 insertions, 14 deletions
diff --git a/lldb/include/lldb/Host/Debug.h b/lldb/include/lldb/Host/Debug.h new file mode 100644 index 00000000000..2cb758e1b73 --- /dev/null +++ b/lldb/include/lldb/Host/Debug.h @@ -0,0 +1,406 @@ +//===-- Debug.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_Debug_h_ +#define liblldb_Debug_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/Mutex.h" +#include <vector> + +namespace lldb_private { + + //------------------------------------------------------------------ + // Tells a thread what it needs to do when the process is resumed. + //------------------------------------------------------------------ + struct ResumeAction + { + lldb::tid_t tid; // The thread ID that this action applies to, LLDB_INVALID_THREAD_ID for the default thread action + lldb::StateType state; // Valid values are eStateStopped/eStateSuspended, eStateRunning, and eStateStepping. + int signal; // When resuming this thread, resume it with this signal if this value is > 0 + }; + + //------------------------------------------------------------------ + // A class that contains instructions for all threads for + // NativeProcessProtocol::Resume(). Each thread can either run, stay + // suspended, or step when the process is resumed. We optionally + // have the ability to also send a signal to the thread when the + // action is run or step. + //------------------------------------------------------------------ + class ResumeActionList + { + public: + ResumeActionList () : + m_actions (), + m_signal_handled () + { + } + + ResumeActionList (lldb::StateType default_action, int signal) : + m_actions(), + m_signal_handled () + { + SetDefaultThreadActionIfNeeded (default_action, signal); + } + + + ResumeActionList (const ResumeAction *actions, size_t num_actions) : + m_actions (), + m_signal_handled () + { + if (actions && num_actions) + { + m_actions.assign (actions, actions + num_actions); + m_signal_handled.assign (num_actions, false); + } + } + + ~ResumeActionList() + { + } + + bool + IsEmpty() const + { + return m_actions.empty(); + } + + void + Append (const ResumeAction &action) + { + m_actions.push_back (action); + m_signal_handled.push_back (false); + } + + void + AppendAction (lldb::tid_t tid, + lldb::StateType state, + int signal = 0) + { + ResumeAction action = { tid, state, signal }; + Append (action); + } + + void + AppendResumeAll () + { + AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateRunning); + } + + void + AppendSuspendAll () + { + AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStopped); + } + + void + AppendStepAll () + { + AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStepping); + } + + const ResumeAction * + GetActionForThread (lldb::tid_t tid, bool default_ok) const + { + const size_t num_actions = m_actions.size(); + for (size_t i=0; i<num_actions; ++i) + { + if (m_actions[i].tid == tid) + return &m_actions[i]; + } + if (default_ok && tid != LLDB_INVALID_THREAD_ID) + return GetActionForThread (LLDB_INVALID_THREAD_ID, false); + return NULL; + } + + size_t + NumActionsWithState (lldb::StateType state) const + { + size_t count = 0; + const size_t num_actions = m_actions.size(); + for (size_t i=0; i<num_actions; ++i) + { + if (m_actions[i].state == state) + ++count; + } + return count; + } + + bool + SetDefaultThreadActionIfNeeded (lldb::StateType action, int signal) + { + if (GetActionForThread (LLDB_INVALID_THREAD_ID, true) == NULL) + { + // There isn't a default action so we do need to set it. + ResumeAction default_action = {LLDB_INVALID_THREAD_ID, action, signal }; + m_actions.push_back (default_action); + m_signal_handled.push_back (false); + return true; // Return true as we did add the default action + } + return false; + } + + void + SetSignalHandledForThread (lldb::tid_t tid) const + { + if (tid != LLDB_INVALID_THREAD_ID) + { + const size_t num_actions = m_actions.size(); + for (size_t i=0; i<num_actions; ++i) + { + if (m_actions[i].tid == tid) + m_signal_handled[i] = true; + } + } + } + + const ResumeAction * + GetFirst() const + { + return m_actions.data(); + } + + size_t + GetSize () const + { + return m_actions.size(); + } + + void + Clear() + { + m_actions.clear(); + m_signal_handled.clear(); + } + + protected: + std::vector<ResumeAction> m_actions; + mutable std::vector<bool> m_signal_handled; + }; + + struct ThreadStopInfo + { + lldb::StopReason reason; + union + { + // eStopTypeSignal + struct + { + uint32_t signo; + } signal; + + // eStopTypeException + struct + { + uint64_t type; + uint32_t data_count; + lldb::addr_t data[2]; + } exception; + } details; + }; + + //------------------------------------------------------------------ + // NativeThreadProtocol + //------------------------------------------------------------------ + class NativeThreadProtocol { + + public: + NativeThreadProtocol (NativeProcessProtocol *process, lldb::tid_t tid) : + m_process (process), + m_tid (tid) + { + } + + virtual ~NativeThreadProtocol() + { + } + virtual const char *GetName() = 0; + virtual lldb::StateType GetState () = 0; + virtual Error ReadRegister (uint32_t reg, RegisterValue ®_value) = 0; + virtual Error WriteRegister (uint32_t reg, const RegisterValue ®_value) = 0; + virtual Error SaveAllRegisters (lldb::DataBufferSP &data_sp) = 0; + virtual Error RestoreAllRegisters (lldb::DataBufferSP &data_sp) = 0; + virtual bool GetStopReason (ThreadStopInfo &stop_info) = 0; + + lldb::tid_t + GetID() const + { + return m_tid; + } + protected: + NativeProcessProtocol *m_process; + lldb::tid_t m_tid; + }; + + + //------------------------------------------------------------------ + // NativeProcessProtocol + //------------------------------------------------------------------ + class NativeProcessProtocol { + public: + + static NativeProcessProtocol * + CreateInstance (lldb::pid_t pid); + + // lldb_private::Host calls should be used to launch a process for debugging, and + // then the process should be attached to. When attaching to a process + // lldb_private::Host calls should be used to locate the process to attach to, + // and then this function should be called. + NativeProcessProtocol (lldb::pid_t pid) : + m_pid (pid), + m_threads(), + m_threads_mutex (Mutex::eMutexTypeRecursive), + m_state (lldb::eStateInvalid), + m_exit_status(0), + m_exit_description() + { + } + + public: + virtual ~NativeProcessProtocol () + { + } + + virtual Error Resume (const ResumeActionList &resume_actions) = 0; + virtual Error Halt () = 0; + virtual Error Detach () = 0; + virtual Error Signal (int signo) = 0; + virtual Error Kill () = 0; + + virtual Error ReadMemory (lldb::addr_t addr, void *buf, lldb::addr_t size, lldb::addr_t &bytes_read) = 0; + virtual Error WriteMemory (lldb::addr_t addr, const void *buf, lldb::addr_t size, lldb::addr_t &bytes_written) = 0; + virtual Error AllocateMemory (lldb::addr_t size, uint32_t permissions, lldb::addr_t &addr) = 0; + virtual Error DeallocateMemory (lldb::addr_t addr) = 0; + + virtual lldb::addr_t GetSharedLibraryInfoAddress () = 0; + + virtual bool IsAlive () = 0; + virtual size_t UpdateThreads () = 0; + virtual bool GetArchitecture (ArchSpec &arch) = 0; + + //---------------------------------------------------------------------- + // Breakpoint functions + //---------------------------------------------------------------------- + virtual Error SetBreakpoint (lldb::addr_t addr, size_t size, bool hardware) = 0; + virtual Error RemoveBreakpoint (lldb::addr_t addr, size_t size) = 0; + + //---------------------------------------------------------------------- + // Watchpoint functions + //---------------------------------------------------------------------- + virtual uint32_t GetMaxWatchpoints () = 0; + virtual Error SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) = 0; + virtual Error RemoveWatchpoint (lldb::addr_t addr) = 0; + + + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- + lldb::pid_t + GetID() const + { + return m_pid; + } + + lldb::StateType + GetState () const + { + return m_state; + } + + bool + IsRunning () const + { + return m_state == lldb::eStateRunning || IsStepping(); + } + + bool + IsStepping () const + { + return m_state == lldb::eStateStepping; + } + + bool + CanResume () const + { + return m_state == lldb::eStateStopped; + } + + + void + SetState (lldb::StateType state) + { + m_state = state; + } + + //---------------------------------------------------------------------- + // Exit Status + //---------------------------------------------------------------------- + virtual bool + GetExitStatus (int *status) + { + if (m_state == lldb::eStateExited) + { + *status = m_exit_status; + return true; + } + *status = 0; + return false; + } + virtual bool + SetExitStatus (int status, const char *exit_description) + { + // Exit status already set + if (m_state == lldb::eStateExited) + return false; + m_state = lldb::eStateExited; + m_exit_status = status; + if (exit_description && exit_description[0]) + m_exit_description = exit_description; + else + m_exit_description.clear(); + return true; + } + + //---------------------------------------------------------------------- + // Access to threads + //---------------------------------------------------------------------- + lldb::NativeThreadProtocolSP + GetThreadAtIndex (uint32_t idx) + { + Mutex::Locker locker(m_threads_mutex); + if (idx < m_threads.size()) + return m_threads[idx]; + return lldb::NativeThreadProtocolSP(); + } + + lldb::NativeThreadProtocolSP + GetThreadByID (lldb::tid_t tid) + { + Mutex::Locker locker(m_threads_mutex); + for (auto thread_sp : m_threads) + { + if (thread_sp->GetID() == tid) + return thread_sp; + } + return lldb::NativeThreadProtocolSP(); + } + + protected: + lldb::pid_t m_pid; + std::vector<lldb::NativeThreadProtocolSP> m_threads; + mutable Mutex m_threads_mutex; + lldb::StateType m_state; + int m_exit_status; + std::string m_exit_description; + }; + +} +#endif // #ifndef liblldb_Debug_h_ diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index f73b59c61b9..41d3ce6e2e1 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -458,6 +458,11 @@ 26D55235159A7DB100708D8D /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26D55234159A7DB100708D8D /* libxml2.dylib */; }; 26D5E15F135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D5E15E135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp */; }; 26D5E163135BB054006EA0A7 /* OptionGroupPlatform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D5E162135BB054006EA0A7 /* OptionGroupPlatform.cpp */; }; + 26D6F3F6183E7F9300194858 /* lldb-gdbserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D6F3F4183E7F9300194858 /* lldb-gdbserver.cpp */; }; + 26D6F3FA183E888800194858 /* liblldb-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2689FFCA13353D7A00698AC0 /* liblldb-core.a */; }; + 26D6F3FB183E88D500194858 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26D55234159A7DB100708D8D /* libxml2.dylib */; }; + 26D6F3FC183E88DD00194858 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C39010F3FA26009D5894 /* CoreFoundation.framework */; }; + 26D6F3FD183E88F000194858 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDB919B414F6F10D008FF64B /* Security.framework */; }; 26D7E45D13D5E30A007FD12B /* SocketAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D7E45C13D5E30A007FD12B /* SocketAddress.cpp */; }; 26DAED6015D327A200E15819 /* OptionValuePathMappings.h in Headers */ = {isa = PBXBuildFile; fileRef = 26DAED5F15D327A200E15819 /* OptionValuePathMappings.h */; }; 26DAED6315D327C200E15819 /* OptionValuePathMappings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DAED6215D327C200E15819 /* OptionValuePathMappings.cpp */; }; @@ -727,6 +732,13 @@ remoteGlobalIDString = 26F5C26910F3D9A4009D5894; remoteInfo = "lldb-tool"; }; + 26D6F3F8183E80BD00194858 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2689FFC913353D7A00698AC0; + remoteInfo = "lldb-core"; + }; 26DC6A151337FE7300FF7998 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -744,6 +756,15 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 26D6F3E5183E7F4E00194858 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; AF90106415AB7D2900FF120D /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -1397,6 +1418,8 @@ 26D5E160135BAEB0006EA0A7 /* OptionGroupArchitecture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupArchitecture.h; path = include/lldb/Interpreter/OptionGroupArchitecture.h; sourceTree = "<group>"; }; 26D5E161135BB040006EA0A7 /* OptionGroupPlatform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupPlatform.h; path = include/lldb/Interpreter/OptionGroupPlatform.h; sourceTree = "<group>"; }; 26D5E162135BB054006EA0A7 /* OptionGroupPlatform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupPlatform.cpp; path = source/Interpreter/OptionGroupPlatform.cpp; sourceTree = "<group>"; }; + 26D6F3E7183E7F4E00194858 /* lldb-gdbserver */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-gdbserver"; sourceTree = BUILT_PRODUCTS_DIR; }; + 26D6F3F4183E7F9300194858 /* lldb-gdbserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "lldb-gdbserver.cpp"; sourceTree = "<group>"; }; 26D7E45B13D5E2F9007FD12B /* SocketAddress.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SocketAddress.h; path = include/lldb/Host/SocketAddress.h; sourceTree = "<group>"; }; 26D7E45C13D5E30A007FD12B /* SocketAddress.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocketAddress.cpp; path = source/Host/common/SocketAddress.cpp; sourceTree = "<group>"; }; 26D9FDC612F784E60003F2EE /* EmulateInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EmulateInstruction.h; path = include/lldb/Core/EmulateInstruction.h; sourceTree = "<group>"; }; @@ -1837,6 +1860,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 26D6F3E4183E7F4E00194858 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 26D6F3FD183E88F000194858 /* Security.framework in Frameworks */, + 26D6F3FC183E88DD00194858 /* CoreFoundation.framework in Frameworks */, + 26D6F3FB183E88D500194858 /* libxml2.dylib in Frameworks */, + 26D6F3FA183E888800194858 /* liblldb-core.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 26DC6A0E1337FE6900FF7998 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1926,6 +1960,7 @@ 26DC6A101337FE6900FF7998 /* lldb-platform */, EDC6D49914E5C19B001B75F8 /* com.apple.lldb.launcherXPCService.xpc */, EDE274EC14EDCE1F005B0F75 /* com.apple.lldb.launcherRootXPCService.xpc */, + 26D6F3E7183E7F4E00194858 /* lldb-gdbserver */, ); name = Products; sourceTree = "<group>"; @@ -3249,6 +3284,15 @@ path = MacOSX; sourceTree = "<group>"; }; + 26D6F3F2183E7F9300194858 /* lldb-gdbserver */ = { + isa = PBXGroup; + children = ( + 26D6F3F4183E7F9300194858 /* lldb-gdbserver.cpp */, + ); + name = "lldb-gdbserver"; + path = "tools/lldb-gdbserver"; + sourceTree = "<group>"; + }; 26D9FDCA12F785120003F2EE /* Instruction */ = { isa = PBXGroup; children = ( @@ -3329,6 +3373,7 @@ 265E9BE0115C2B8500D0DCCB /* debugserver */, 26F5C22510F3D956009D5894 /* Driver */, 2665CD0915080846002C8FAE /* install-headers */, + 26D6F3F2183E7F9300194858 /* lldb-gdbserver */, 26DC6A1B1337FEA400FF7998 /* lldb-platform */, ); name = Tools; @@ -3762,6 +3807,24 @@ productReference = 2689FFCA13353D7A00698AC0 /* liblldb-core.a */; productType = "com.apple.product-type.library.dynamic"; }; + 26D6F3E6183E7F4E00194858 /* lldb-gdbserver */ = { + isa = PBXNativeTarget; + buildConfigurationList = 26D6F3F1183E7F4F00194858 /* Build configuration list for PBXNativeTarget "lldb-gdbserver" */; + buildPhases = ( + 26D6F3E3183E7F4E00194858 /* Sources */, + 26D6F3E4183E7F4E00194858 /* Frameworks */, + 26D6F3E5183E7F4E00194858 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 26D6F3F9183E80BD00194858 /* PBXTargetDependency */, + ); + name = "lldb-gdbserver"; + productName = "lldb-gdbserver"; + productReference = 26D6F3E7183E7F4E00194858 /* lldb-gdbserver */; + productType = "com.apple.product-type.tool"; + }; 26DC6A0F1337FE6900FF7998 /* lldb-platform */ = { isa = PBXNativeTarget; buildConfigurationList = 26DC6A1A1337FE8B00FF7998 /* Build configuration list for PBXNativeTarget "lldb-platform" */; @@ -3862,6 +3925,7 @@ 26680206115FD0ED008E1FE4 /* LLDB */, 26579F67126A25920007C5CB /* darwin-debug */, 2689FFC913353D7A00698AC0 /* lldb-core */, + 26D6F3E6183E7F4E00194858 /* lldb-gdbserver */, 26DC6A0F1337FE6900FF7998 /* lldb-platform */, EDC6D49814E5C19B001B75F8 /* launcherXPCService */, EDE274E214EDCE1F005B0F75 /* launcherRootXPCService */, @@ -4444,6 +4508,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 26D6F3E3183E7F4E00194858 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 26D6F3F6183E7F9300194858 /* lldb-gdbserver.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 26DC6A0D1337FE6900FF7998 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4543,6 +4615,11 @@ target = 26F5C26910F3D9A4009D5894 /* lldb-tool */; targetProxy = 26CEF3C114FD5973007286B2 /* PBXContainerItemProxy */; }; + 26D6F3F9183E80BD00194858 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2689FFC913353D7A00698AC0 /* lldb-core */; + targetProxy = 26D6F3F8183E80BD00194858 /* PBXContainerItemProxy */; + }; 26DC6A161337FE7300FF7998 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 2689FFC913353D7A00698AC0 /* lldb-core */; @@ -5220,6 +5297,283 @@ }; name = BuildAndIntegration; }; + 26D6F3ED183E7F4F00194858 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign; + DEAD_CODE_STRIPPING = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + ); + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_PREPROCESSOR_DEFINITIONS = ( + "-lobjc", + "-lpython", + "-framework", + DebugSymbols, + "-framework", + Carbon, + "-framework", + Foundation, + "-framework", + AppKit, + "-v", + "-Wl,-v", + ); + LIBRARY_SEARCH_PATHS = ( + "$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)", + "$(inherited)", + ); + OTHER_LDFLAGS = ( + "-lllvmclang", + "-lpython", + "-lxml2", + "-framework", + DebugSymbols, + "-framework", + Carbon, + "-framework", + Foundation, + "-framework", + AppKit, + "-v", + "-Wl,-v", + ); + "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = ( + "-lllvmclang", + "-framework", + Foundation, + "-framework", + UIKit, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include"; + }; + name = Debug; + }; + 26D6F3EE183E7F4F00194858 /* DebugClang */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign; + DEAD_CODE_STRIPPING = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + ); + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_PREPROCESSOR_DEFINITIONS = ( + "-lobjc", + "-lpython", + "-framework", + DebugSymbols, + "-framework", + Carbon, + "-framework", + Foundation, + "-framework", + AppKit, + "-v", + "-Wl,-v", + ); + LIBRARY_SEARCH_PATHS = ( + "$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)", + "$(inherited)", + ); + OTHER_LDFLAGS = ( + "-lllvmclang", + "-lpython", + "-framework", + DebugSymbols, + "-framework", + Carbon, + "-framework", + Foundation, + "-framework", + AppKit, + "-v", + "-Wl,-v", + ); + "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = ( + "-lllvmclang", + "-framework", + Foundation, + "-framework", + UIKit, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include"; + }; + name = DebugClang; + }; + 26D6F3EF183E7F4F00194858 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + ENABLE_NS_ASSERTIONS = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + ); + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_PREPROCESSOR_DEFINITIONS = ( + "-lobjc", + "-lpython", + "-framework", + DebugSymbols, + "-framework", + Carbon, + "-framework", + Foundation, + "-framework", + AppKit, + "-v", + "-Wl,-v", + ); + LIBRARY_SEARCH_PATHS = ( + "$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)", + "$(inherited)", + ); + OTHER_LDFLAGS = ( + "-lllvmclang", + "-lpython", + "-lxml2", + "-framework", + DebugSymbols, + "-framework", + Carbon, + "-framework", + Foundation, + "-framework", + AppKit, + "-v", + "-Wl,-v", + ); + "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = ( + "-lllvmclang", + "-framework", + Foundation, + "-framework", + UIKit, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include"; + }; + name = Release; + }; + 26D6F3F0183E7F4F00194858 /* BuildAndIntegration */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + ENABLE_NS_ASSERTIONS = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + ); + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_PREPROCESSOR_DEFINITIONS = ( + "-lobjc", + "-lpython", + "-framework", + DebugSymbols, + "-framework", + Carbon, + "-framework", + Foundation, + "-framework", + AppKit, + "-v", + "-Wl,-v", + ); + INSTALL_PATH = "$(LLDB_FRAMEWORK_INSTALL_DIR)/LLDB.framework/Resources"; + LIBRARY_SEARCH_PATHS = ( + "$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)", + "$(inherited)", + ); + OTHER_LDFLAGS = ( + "-lllvmclang", + "-lpython", + "-lxml2", + "-framework", + DebugSymbols, + "-framework", + Carbon, + "-framework", + Foundation, + "-framework", + AppKit, + "-v", + "-Wl,-v", + ); + "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = ( + "-lllvmclang", + "-framework", + Foundation, + "-framework", + UIKit, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRIP_INSTALLED_PRODUCT = YES; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include"; + }; + name = BuildAndIntegration; + }; 26DC6A121337FE6A00FF7998 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5234,7 +5588,6 @@ GCC_ENABLE_CPP_RTTI = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_PREPROCESSOR_DEFINITIONS = ( "-lobjc", "-lpython", @@ -5249,7 +5602,6 @@ "-v", "-Wl,-v", ); - INSTALL_PATH = "$(LLDB_TOOLS_INSTALL_DIR)"; LIBRARY_SEARCH_PATHS = ( "$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)", "$(inherited)", @@ -5277,8 +5629,6 @@ UIKit, ); PRODUCT_NAME = "lldb-platform"; - "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - "PROVISIONING_PROFILE[sdk=macosx*]" = ""; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include"; }; @@ -5296,7 +5646,6 @@ ); GCC_ENABLE_CPP_RTTI = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_PREPROCESSOR_DEFINITIONS = ( "-lobjc", "-lpython", @@ -5311,7 +5660,6 @@ "-v", "-Wl,-v", ); - INSTALL_PATH = "$(LLDB_TOOLS_INSTALL_DIR)"; LIBRARY_SEARCH_PATHS = ( "$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)", "$(inherited)", @@ -5339,8 +5687,6 @@ UIKit, ); PRODUCT_NAME = "lldb-platform"; - "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - "PROVISIONING_PROFILE[sdk=macosx*]" = ""; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include"; }; @@ -5357,7 +5703,6 @@ ); GCC_ENABLE_CPP_RTTI = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_PREPROCESSOR_DEFINITIONS = ( "-lobjc", "-lpython", @@ -5372,7 +5717,7 @@ "-v", "-Wl,-v", ); - INSTALL_PATH = "$(LLDB_TOOLS_INSTALL_DIR)"; + INSTALL_PATH = "$(LLDB_FRAMEWORK_INSTALL_DIR)/LLDB.framework/Resources"; LIBRARY_SEARCH_PATHS = ( "$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)", "$(inherited)", @@ -5695,7 +6040,6 @@ GCC_ENABLE_CPP_RTTI = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_PREPROCESSOR_DEFINITIONS = ( "-lobjc", "-lpython", @@ -5710,7 +6054,6 @@ "-v", "-Wl,-v", ); - INSTALL_PATH = "$(LLDB_TOOLS_INSTALL_DIR)"; LIBRARY_SEARCH_PATHS = ( "$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)", "$(inherited)", @@ -5737,8 +6080,6 @@ UIKit, ); PRODUCT_NAME = "lldb-platform"; - "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - "PROVISIONING_PROFILE[sdk=macosx*]" = ""; SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include"; }; @@ -6120,6 +6461,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = BuildAndIntegration; }; + 26D6F3F1183E7F4F00194858 /* Build configuration list for PBXNativeTarget "lldb-gdbserver" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 26D6F3ED183E7F4F00194858 /* Debug */, + 26D6F3EE183E7F4F00194858 /* DebugClang */, + 26D6F3EF183E7F4F00194858 /* Release */, + 26D6F3F0183E7F4F00194858 /* BuildAndIntegration */, + ); + defaultConfigurationIsVisible = 0; + }; 26DC6A1A1337FE8B00FF7998 /* Build configuration list for PBXNativeTarget "lldb-platform" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/lldb/tools/lldb-gdbserver/CMakeLists.txt b/lldb/tools/lldb-gdbserver/CMakeLists.txt new file mode 100644 index 00000000000..9c1599a1e7f --- /dev/null +++ b/lldb/tools/lldb-gdbserver/CMakeLists.txt @@ -0,0 +1,14 @@ +set(LLVM_NO_RTTI 1) + +include_directories(../../source) + +add_lldb_executable(lldb-gdbserver + lldb-gdbserver.cpp + ) + +target_link_libraries(lldb-gdbserver liblldb) + +set_target_properties(lldb-gdbserver PROPERTIES VERSION ${LLDB_VERSION}) + +install(TARGETS lldb-gdbserver + RUNTIME DESTINATION bin) diff --git a/lldb/tools/lldb-gdbserver/Makefile b/lldb/tools/lldb-gdbserver/Makefile new file mode 100644 index 00000000000..41425a139a8 --- /dev/null +++ b/lldb/tools/lldb-gdbserver/Makefile @@ -0,0 +1,23 @@ +##===- tools/lldb-platform/Makefile ------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LLDB_LEVEL := ../.. + +TOOLNAME = lldb-gdbserver + +LLVMLibsOptions += -llldb -llldbUtility + +include $(LLDB_LEVEL)/Makefile + +ifeq ($(HOST_OS),Darwin) + LLVMLibsOptions += -Wl,-rpath,@loader_path/../lib/ +endif + +ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD GNU/kFreeBSD)) + LLVMLibsOptions += -Wl,-rpath,$(LibDir) +endif diff --git a/lldb/tools/lldb-gdbserver/lldb-gdbserver.cpp b/lldb/tools/lldb-gdbserver/lldb-gdbserver.cpp new file mode 100644 index 00000000000..26b9b2d19eb --- /dev/null +++ b/lldb/tools/lldb-gdbserver/lldb-gdbserver.cpp @@ -0,0 +1,240 @@ +//===-- lldb-gdbserver.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" + +// C Includes +#include <errno.h> +#include <getopt.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// C++ Includes + +// Other libraries and framework includes +#include "lldb/lldb-private-log.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/ConnectionFileDescriptor.h" +#include "lldb/Core/ConnectionMachPort.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/StreamFile.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h" +#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// option descriptors for getopt_long_only() +//---------------------------------------------------------------------- + +int g_debug = 0; +int g_verbose = 0; + +static struct option g_long_options[] = +{ + { "debug", no_argument, &g_debug, 1 }, + { "verbose", no_argument, &g_verbose, 1 }, + { "log-file", required_argument, NULL, 'l' }, + { "log-flags", required_argument, NULL, 'f' }, + { NULL, 0, NULL, 0 } +}; + + +//---------------------------------------------------------------------- +// Watch for signals +//---------------------------------------------------------------------- +int g_sigpipe_received = 0; +void +signal_handler(int signo) +{ + switch (signo) + { + case SIGPIPE: + g_sigpipe_received = 1; + break; + case SIGHUP: + // Use SIGINT first, if that does not work, use SIGHUP as a last resort. + // And we should not call exit() here because it results in the global destructors + // to be invoked and wreaking havoc on the threads still running. + Host::SystemLog(Host::eSystemLogWarning, "SIGHUP received, exiting lldb-gdbserver...\n"); + abort(); + break; + } +} + +static void +display_usage (const char *progname) +{ + fprintf(stderr, "Usage:\n %s [--log-file log-file-path] [--log-flags flags] HOST:PORT [-- PROGRAM ARG1 ARG2 ...]\n", progname); + exit(0); +} + +//---------------------------------------------------------------------- +// main +//---------------------------------------------------------------------- +int +main (int argc, char *argv[]) +{ + const char *progname = argv[0]; + signal (SIGPIPE, signal_handler); + signal (SIGHUP, signal_handler); + int long_option_index = 0; + StreamSP log_stream_sp; + Args log_args; + Error error; + int ch; + Debugger::Initialize(); + + bool show_usage = false; + int option_error = 0; +// StreamSP stream_sp (new StreamFile(stdout, false)); +// const char *log_channels[] = { "host", "process", NULL }; +// EnableLog (stream_sp, 0, log_channels, NULL); + + while ((ch = getopt_long_only(argc, argv, "l:f:h", g_long_options, &long_option_index)) != -1) + { +// DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n", +// ch, (uint8_t)ch, +// g_long_options[long_option_index].name, +// g_long_options[long_option_index].has_arg ? '=' : ' ', +// optarg ? optarg : ""); + switch (ch) + { + case 0: // Any optional that auto set themselves will return 0 + break; + + case 'l': // Set Log File + if (optarg && optarg[0]) + { + if ((strcasecmp(optarg, "stdout") == 0) || (strcmp(optarg, "/dev/stdout") == 0)) + { + log_stream_sp.reset (new StreamFile (stdout, false)); + } + else if ((strcasecmp(optarg, "stderr") == 0) || (strcmp(optarg, "/dev/stderr") == 0)) + { + log_stream_sp.reset (new StreamFile (stderr, false)); + } + else + { + FILE *log_file = fopen(optarg, "w"); + if (log_file) + { + setlinebuf(log_file); + log_stream_sp.reset (new StreamFile (log_file, true)); + } + else + { + const char *errno_str = strerror(errno); + fprintf (stderr, "Failed to open log file '%s' for writing: errno = %i (%s)", optarg, errno, errno_str ? errno_str : "unknown error"); + } + + } + + } + break; + + case 'f': // Log Flags + if (optarg && optarg[0]) + log_args.AppendArgument(optarg); + break; + + case 'h': /* fall-through is intentional */ + case '?': + show_usage = true; + break; + } + } + + if (show_usage || option_error) + { + display_usage(progname); + exit(option_error); + } + + if (log_stream_sp) + { + if (log_args.GetArgumentCount() == 0) + log_args.AppendArgument("default"); + ProcessGDBRemoteLog::EnableLog (log_stream_sp, 0,log_args.GetConstArgumentVector(), log_stream_sp.get()); + } + + // Skip any options we consumed with getopt_long_only + argc -= optind; + argv += optind; + + if (argc == 0) + { + display_usage(progname); + exit(255); + } + + const char *host_and_port = argv[0]; + argc -= 1; + argv += 1; + // Any arguments left over are for the the program that we need to launch. If there + // are no arguments, then the GDB server will start up and wait for an 'A' packet + // to launch a program, or a vAttach packet to attach to an existing process. + + const bool is_platform = false; + GDBRemoteCommunicationServer gdb_server (is_platform); + + if (host_and_port && host_and_port[0]) + { + std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); + if (conn_ap.get()) + { + std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); + if (conn_ap.get()) + { + std::string connect_url ("listen://"); + connect_url.append(host_and_port); + + printf ("Listening for a connection on %s...\n", host_and_port); + if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess) + { + printf ("Connection established.\n"); + gdb_server.SetConnection (conn_ap.release()); + } + } + } + + if (gdb_server.IsConnected()) + { + // After we connected, we need to get an initial ack from... + if (gdb_server.HandshakeWithClient(&error)) + { + bool interrupt = false; + bool done = false; + while (!interrupt && !done) + { + if (!gdb_server.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done)) + break; + } + + if (error.Fail()) + { + fprintf(stderr, "error: %s\n", error.AsCString()); + } + } + else + { + fprintf(stderr, "error: handshake with client failed\n"); + } + } + } + + Debugger::Terminate(); + + fprintf(stderr, "lldb-gdbserver exiting...\n"); + + return 0; +} |

