Index: tools/driver/Makefile =================================================================== --- tools/driver/Makefile (revision 147532) +++ tools/driver/Makefile (working copy) @@ -25,7 +25,6 @@ ifeq ($(HOST_OS),FreeBSD) CPP.Flags += -I/usr/include/edit #-v - LD.Flags += -lEnhancedDisassembly LD.Flags += -Wl,-rpath,$(LibDir) endif Index: lib/Makefile =================================================================== --- lib/Makefile (revision 147532) +++ lib/Makefile (working copy) @@ -81,15 +81,19 @@ endif ifeq ($(HOST_OS),Linux) - USEDLIBS += lldbPluginProcessLinux.a \ - lldbPluginDynamicLoaderLinux.a \ + USEDLIBS += lldbPluginProcessPOSIX.a \ + lldbPluginProcessLinux.a \ + lldbPluginDynamicLoaderPOSIX.a \ lldbPluginPlatformLinux.a \ lldbHostLinux.a endif ifeq ($(HOST_OS),FreeBSD) USEDLIBS += lldbHostFreeBSD.a \ - lldbPluginPlatformFreeBSD.a + lldbPluginDynamicLoaderPOSIX.a \ + lldbPluginProcessPOSIX.a \ + lldbPluginProcessFreeBSD.a \ + lldbPluginPlatformFreeBSD.a endif include $(LEVEL)/Makefile.common @@ -131,7 +135,7 @@ ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \ -Wl,--no-whole-archive # Don't allow unresolved symbols. - LLVMLibsOptions += -Wl,--no-undefined + LLVMLibsOptions += -Wl,--allow-shlib-undefined # Link in python LD.Flags += $(PYTHON_BUILD_FLAGS) -lrt -L/usr/local/lib -lexecinfo endif Index: Makefile =================================================================== --- Makefile (revision 147532) +++ Makefile (working copy) @@ -39,6 +39,7 @@ CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Utility CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/Utility +CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/POSIX ifeq ($(HOST_OS),Darwin) CPP.Flags += -F/System/Library/Frameworks -F/System/Library/PrivateFrameworks endif Index: include/lldb/Target/Platform.h =================================================================== --- include/lldb/Target/Platform.h (revision 147532) +++ include/lldb/Target/Platform.h (working copy) @@ -146,6 +146,10 @@ virtual const char * GetDescription () = 0; + /// By default, launch the process by spawning and attaching. + virtual bool + CanLaunchViaAttach () { return true; } + //------------------------------------------------------------------ /// Report the current status for this platform. /// Index: include/lldb/Host/Host.h =================================================================== --- include/lldb/Host/Host.h (revision 147532) +++ include/lldb/Host/Host.h (working copy) @@ -355,7 +355,10 @@ static Error LaunchProcess (ProcessLaunchInfo &launch_info); - + + static lldb::DataBufferSP + GetAuxvData (lldb_private::Process *process); + static lldb::TargetSP GetDummyTarget (Debugger &debugger); Index: source/Plugins/Platform/Linux/PlatformLinux.h =================================================================== --- source/Plugins/Platform/Linux/PlatformLinux.h (revision 147532) +++ source/Plugins/Platform/Linux/PlatformLinux.h (working copy) @@ -66,6 +66,10 @@ return 1; } + /// Linux processes can not be launched by spawning and attaching. + virtual bool + CanLaunchViaAttach () { return false; } + //------------------------------------------------------------ // lldb_private::Platform functions //------------------------------------------------------------ Index: source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp =================================================================== --- source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp (revision 147532) +++ source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp (working copy) @@ -27,16 +27,13 @@ Platform * PlatformFreeBSD::CreateInstance () { - // The only time we create an instance is when we are creating a remote - // freebsd platform - const bool is_host = false; - return new PlatformFreeBSD (is_host); + return new PlatformFreeBSD (true); } const char * PlatformFreeBSD::GetPluginNameStatic() { - return "PlatformFreeBSD"; + return "plugin.platform.freebsd"; } const char * @@ -66,7 +63,7 @@ { #if defined (__FreeBSD__) PlatformSP default_platform_sp (CreateInstance()); - //default_platform_sp->SetSystemArchitecture (Host::GetArchitecture()); + default_platform_sp->SetSystemArchitecture (Host::GetArchitecture()); Platform::SetDefaultPlatform (default_platform_sp); #endif PluginManager::RegisterPlugin(PlatformFreeBSD::GetShortPluginNameStatic(false), @@ -385,17 +382,17 @@ bool PlatformFreeBSD::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) { - bool sucess = false; + bool success = false; if (IsHost()) { - sucess = Platform::GetProcessInfo (pid, process_info); + success = Platform::GetProcessInfo (pid, process_info); + } - else + else if (m_remote_platform_sp) { - if (m_remote_platform_sp) - sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info); + success = m_remote_platform_sp->GetProcessInfo (pid, process_info); } - return sucess; + return success; } @@ -438,11 +435,11 @@ } lldb::ProcessSP -PlatformFreeBSD::Attach(lldb::pid_t pid, - Debugger &debugger, - Target *target, - Listener &listener, - Error &error) +PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info, + Debugger &debugger, + Target *target, + Listener &listener, + Error &error) { lldb::ProcessSP process_sp; if (IsHost()) @@ -457,6 +454,7 @@ emptyFileSpec, emptyArchSpec, false, + m_remote_platform_sp, new_target_sp); target = new_target_sp.get(); } @@ -472,13 +470,13 @@ process_sp = target->CreateProcess (listener, "gdb-remote"); if (process_sp) - error = process_sp->Attach (pid); + error = process_sp->Attach (attach_info); } } else { if (m_remote_platform_sp) - process_sp = m_remote_platform_sp->Attach (pid, debugger, target, listener, error); + process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); else error.SetErrorString ("the platform is not currently connected"); } Index: source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h =================================================================== --- source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h (revision 147532) +++ source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h (working copy) @@ -77,6 +77,10 @@ return GetDescriptionStatic(IsHost()); } + /// FreeBSD processes can not be launched by spawning and attaching. + virtual bool + CanLaunchViaAttach () { return false; } + //------------------------------------------------------------ // lldb_private::Platform functions //------------------------------------------------------------ @@ -132,7 +136,7 @@ LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info); virtual lldb::ProcessSP - Attach(lldb::pid_t pid, + Attach(lldb_private::ProcessAttachInfo &attach_info, lldb_private::Debugger &debugger, lldb_private::Target *target, lldb_private::Listener &listener, Index: source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp (deleted) =================================================================== Index: source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp (deleted) =================================================================== Index: source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h (deleted) =================================================================== Index: source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h (deleted) =================================================================== Index: source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp (deleted) =================================================================== Index: source/Plugins/DynamicLoader/Linux-DYLD/Makefile (deleted) =================================================================== Index: source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h (deleted) =================================================================== Index: source/Plugins/Makefile =================================================================== --- source/Plugins/Makefile (revision 147532) +++ source/Plugins/Makefile (working copy) @@ -30,7 +30,11 @@ endif ifeq ($(HOST_OS),Linux) -DIRS += Process/Linux DynamicLoader/Linux-DYLD +DIRS += Process/Linux Process/POSIX DynamicLoader/POSIX-DYLD endif +ifeq ($(HOST_OS),FreeBSD) +DIRS += Process/FreeBSD Process/POSIX DynamicLoader/POSIX-DYLD +endif + include $(LLDB_LEVEL)/Makefile Index: source/Plugins/Process/Linux/ProcessLinux.cpp =================================================================== --- source/Plugins/Process/Linux/ProcessLinux.cpp (revision 147532) +++ source/Plugins/Process/Linux/ProcessLinux.cpp (working copy) @@ -20,10 +20,10 @@ #include "lldb/Target/Target.h" #include "ProcessLinux.h" -#include "ProcessLinuxLog.h" +#include "ProcessPOSIXLog.h" #include "Plugins/Process/Utility/InferiorCallPOSIX.h" #include "ProcessMonitor.h" -#include "LinuxThread.h" +#include "POSIXThread.h" using namespace lldb; using namespace lldb_private; @@ -50,42 +50,21 @@ CreateInstance); Log::Callbacks log_callbacks = { - ProcessLinuxLog::DisableLog, - ProcessLinuxLog::EnableLog, - ProcessLinuxLog::ListLogCategories + ProcessPOSIXLog::DisableLog, + ProcessPOSIXLog::EnableLog, + ProcessPOSIXLog::ListLogCategories }; Log::RegisterLogChannel (ProcessLinux::GetPluginNameStatic(), log_callbacks); + ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic()); } } -void -ProcessLinux::Terminate() -{ -} - -const char * -ProcessLinux::GetPluginNameStatic() -{ - return "plugin.process.linux"; -} - -const char * -ProcessLinux::GetPluginDescriptionStatic() -{ - return "Process plugin for Linux"; -} - - //------------------------------------------------------------------------------ // Constructors and destructors. ProcessLinux::ProcessLinux(Target& target, Listener &listener) - : Process(target, listener), - m_monitor(NULL), - m_module(NULL), - m_in_limbo(false), - m_exit_now(false) + : ProcessPOSIX(target, listener) { #if 0 // FIXME: Putting this code in the ctor and saving the byte order in a @@ -98,409 +77,28 @@ #endif } -ProcessLinux::~ProcessLinux() -{ - delete m_monitor; -} - -//------------------------------------------------------------------------------ -// Process protocol. - -bool -ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name) -{ - // For now we are just making sure the file exists for a given module - ModuleSP exe_module_sp(target.GetExecutableModule()); - if (exe_module_sp.get()) - return exe_module_sp->GetFileSpec().Exists(); - return false; -} - -Error -ProcessLinux::DoAttachToProcessWithID(lldb::pid_t pid) -{ - Error error; - assert(m_monitor == NULL); - - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) - log->Printf ("ProcessLinux::%s(pid = %i)", __FUNCTION__, GetID()); - - m_monitor = new ProcessMonitor(this, pid, error); - - if (!error.Success()) - return error; - - SetID(pid); - return error; -} - -Error -ProcessLinux::WillLaunch(Module* module) -{ - Error error; - return error; -} - -Error -ProcessLinux::DoLaunch (Module *module, - const ProcessLaunchInfo &launch_info) -{ - Error error; - assert(m_monitor == NULL); - - SetPrivateState(eStateLaunching); - - const char *stdin_path = NULL; - const char *stdout_path = NULL; - const char *stderr_path = NULL; - const char *working_dir = launch_info.GetWorkingDirectory(); - - const ProcessLaunchInfo::FileAction *file_action; - file_action = launch_info.GetFileActionForFD (STDIN_FILENO); - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - stdin_path = file_action->GetPath(); - } - file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - stdout_path = file_action->GetPath(); - } - file_action = launch_info.GetFileActionForFD (STDERR_FILENO); - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - stderr_path = file_action->GetPath(); - } - - m_monitor = new ProcessMonitor (this, - module, - launch_info.GetArguments().GetConstArgumentVector(), - launch_info.GetEnvironmentEntries().GetConstArgumentVector(), - stdin_path, - stdout_path, - stderr_path, - error); - - m_module = module; - - if (!error.Success()) - return error; - - SetID(m_monitor->GetPID()); - return error; -} - void -ProcessLinux::DidLaunch() +ProcessLinux::Terminate() { } - -Error -ProcessLinux::DoResume() +const char * +ProcessLinux::GetPluginNameStatic() { - StateType state = GetPrivateState(); - - assert(state == eStateStopped || state == eStateCrashed); - - // We are about to resume a thread that will cause the process to exit so - // set our exit status now. Do not change our state if the inferior - // crashed. - if (state == eStateStopped) - { - if (m_in_limbo) - SetExitStatus(m_exit_status, NULL); - else - SetPrivateState(eStateRunning); - } - - bool did_resume = false; - uint32_t thread_count = m_thread_list.GetSize(false); - for (uint32_t i = 0; i < thread_count; ++i) - { - LinuxThread *thread = static_cast( - m_thread_list.GetThreadAtIndex(i, false).get()); - did_resume = thread->Resume() || did_resume; - } - assert(did_resume && "Process resume failed!"); - - return Error(); + return "linux"; } -addr_t -ProcessLinux::GetImageInfoAddress() +const char * +ProcessLinux::GetPluginDescriptionStatic() { - Target *target = &GetTarget(); - ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); - Address addr = obj_file->GetImageInfoAddress(); - - if (addr.IsValid()) - return addr.GetLoadAddress(target); - else - return LLDB_INVALID_ADDRESS; + return "Process plugin for Linux"; } -Error -ProcessLinux::DoHalt(bool &caused_stop) -{ - Error error; - if (IsStopped()) - { - caused_stop = false; - } - else if (kill(GetID(), SIGSTOP)) - { - caused_stop = false; - error.SetErrorToErrno(); - } - else - { - caused_stop = true; - } - - return error; -} - -Error -ProcessLinux::DoDetach() -{ - Error error; - - error = m_monitor->Detach(); - if (error.Success()) - SetPrivateState(eStateDetached); - - return error; -} - -Error -ProcessLinux::DoSignal(int signal) -{ - Error error; - - if (kill(GetID(), signal)) - error.SetErrorToErrno(); - - return error; -} - -Error -ProcessLinux::DoDestroy() -{ - Error error; - - if (!HasExited()) - { - // Drive the exit event to completion (do not keep the inferior in - // limbo). - m_exit_now = true; - - if (kill(m_monitor->GetPID(), SIGKILL) && error.Success()) - { - error.SetErrorToErrno(); - return error; - } - - SetPrivateState(eStateExited); - } - - return error; -} - -void -ProcessLinux::SendMessage(const ProcessMessage &message) -{ - Mutex::Locker lock(m_message_mutex); - - switch (message.GetKind()) - { - default: - assert(false && "Unexpected process message!"); - break; - - case ProcessMessage::eInvalidMessage: - return; - - case ProcessMessage::eLimboMessage: - m_in_limbo = true; - m_exit_status = message.GetExitStatus(); - if (m_exit_now) - { - SetPrivateState(eStateExited); - m_monitor->Detach(); - } - else - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eExitMessage: - m_exit_status = message.GetExitStatus(); - SetExitStatus(m_exit_status, NULL); - break; - - case ProcessMessage::eTraceMessage: - case ProcessMessage::eBreakpointMessage: - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eSignalMessage: - case ProcessMessage::eSignalDeliveredMessage: - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eCrashMessage: - SetPrivateState(eStateCrashed); - break; - } - - m_message_queue.push(message); -} - -void -ProcessLinux::RefreshStateAfterStop() -{ - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) - log->Printf ("ProcessLinux::%s()", __FUNCTION__); - - Mutex::Locker lock(m_message_mutex); - if (m_message_queue.empty()) - return; - - ProcessMessage &message = m_message_queue.front(); - - // Resolve the thread this message corresponds to and pass it along. - // FIXME: we're really dealing with the pid here. This should get - // fixed when this code is fixed to handle multiple threads. - lldb::tid_t tid = message.GetTID(); - if (log) - log->Printf ("ProcessLinux::%s() pid = %i", __FUNCTION__, tid); - LinuxThread *thread = static_cast( - GetThreadList().FindThreadByID(tid, false).get()); - - assert(thread); - thread->Notify(message); - - m_message_queue.pop(); -} - -bool -ProcessLinux::IsAlive() -{ - StateType state = GetPrivateState(); - return state != eStateDetached && state != eStateExited && state != eStateInvalid; -} - -size_t -ProcessLinux::DoReadMemory(addr_t vm_addr, - void *buf, size_t size, Error &error) -{ - assert(m_monitor); - return m_monitor->ReadMemory(vm_addr, buf, size, error); -} - -size_t -ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size, - Error &error) -{ - assert(m_monitor); - return m_monitor->WriteMemory(vm_addr, buf, size, error); -} - -addr_t -ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions, - Error &error) -{ - addr_t allocated_addr = LLDB_INVALID_ADDRESS; - - unsigned prot = 0; - if (permissions & lldb::ePermissionsReadable) - prot |= eMmapProtRead; - if (permissions & lldb::ePermissionsWritable) - prot |= eMmapProtWrite; - if (permissions & lldb::ePermissionsExecutable) - prot |= eMmapProtExec; - - if (InferiorCallMmap(this, allocated_addr, 0, size, prot, - eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) { - m_addr_to_mmap_size[allocated_addr] = size; - error.Clear(); - } else { - allocated_addr = LLDB_INVALID_ADDRESS; - error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions)); - } - - return allocated_addr; -} - -Error -ProcessLinux::DoDeallocateMemory(lldb::addr_t addr) -{ - Error error; - MMapMap::iterator pos = m_addr_to_mmap_size.find(addr); - if (pos != m_addr_to_mmap_size.end() && - InferiorCallMunmap(this, addr, pos->second)) - m_addr_to_mmap_size.erase (pos); - else - error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr); - - return error; -} - -size_t -ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site) -{ - static const uint8_t g_i386_opcode[] = { 0xCC }; - - ArchSpec arch = GetTarget().GetArchitecture(); - const uint8_t *opcode = NULL; - size_t opcode_size = 0; - - switch (arch.GetCore()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_64_x86_64: - opcode = g_i386_opcode; - opcode_size = sizeof(g_i386_opcode); - break; - } - - bp_site->SetTrapOpcode(opcode, opcode_size); - return opcode_size; -} - -Error -ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site) -{ - return EnableSoftwareBreakpoint(bp_site); -} - -Error -ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site) -{ - return DisableSoftwareBreakpoint(bp_site); -} - uint32_t -ProcessLinux::UpdateThreadListIfNeeded() -{ - // Do not allow recursive updates. - return m_thread_list.GetSize(false); -} - -uint32_t ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessLinux::%s() (pid = %i)", __FUNCTION__, GetID()); // Update the process thread list with this new thread. @@ -508,62 +106,16 @@ assert(m_monitor); ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false)); if (!thread_sp) - thread_sp.reset(new LinuxThread(*this, GetID())); + thread_sp.reset(new POSIXThread(*this, GetID())); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessLinux::%s() updated pid = %i", __FUNCTION__, GetID()); new_thread_list.AddThread(thread_sp); return new_thread_list.GetSize(false); } -ByteOrder -ProcessLinux::GetByteOrder() const -{ - // FIXME: We should be able to extract this value directly. See comment in - // ProcessLinux(). - return m_byte_order; -} -size_t -ProcessLinux::PutSTDIN(const char *buf, size_t len, Error &error) -{ - ssize_t status; - if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) - { - error.SetErrorToErrno(); - return 0; - } - return status; -} - -size_t -ProcessLinux::GetSTDOUT(char *buf, size_t len, Error &error) -{ - ssize_t bytes_read; - - // The terminal file descriptor is always in non-block mode. - if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0) - { - if (errno != EAGAIN) - error.SetErrorToErrno(); - return 0; - } - return bytes_read; -} - -size_t -ProcessLinux::GetSTDERR(char *buf, size_t len, Error &error) -{ - return GetSTDOUT(buf, len, error); -} - -UnixSignals & -ProcessLinux::GetUnixSignals() -{ - return m_linux_signals; -} - //------------------------------------------------------------------------------ // ProcessInterface protocol. @@ -601,39 +153,3 @@ { return NULL; } - -//------------------------------------------------------------------------------ -// Utility functions. - -bool -ProcessLinux::HasExited() -{ - switch (GetPrivateState()) - { - default: - break; - - case eStateDetached: - case eStateExited: - return true; - } - - return false; -} - -bool -ProcessLinux::IsStopped() -{ - switch (GetPrivateState()) - { - default: - break; - - case eStateStopped: - case eStateCrashed: - case eStateSuspended: - return true; - } - - return false; -} Index: source/Plugins/Process/Linux/ProcessLinuxLog.cpp (deleted) =================================================================== Index: source/Plugins/Process/Linux/ProcessLinux.h =================================================================== --- source/Plugins/Process/Linux/ProcessLinux.h (revision 147532) +++ source/Plugins/Process/Linux/ProcessLinux.h (working copy) @@ -19,11 +19,12 @@ #include "lldb/Target/Process.h" #include "LinuxSignals.h" #include "ProcessMessage.h" +#include "ProcessPOSIX.h" class ProcessMonitor; class ProcessLinux : - public lldb_private::Process + public ProcessPOSIX { public: //------------------------------------------------------------------ @@ -51,97 +52,8 @@ ProcessLinux(lldb_private::Target& target, lldb_private::Listener &listener); - virtual - ~ProcessLinux(); - - //------------------------------------------------------------------ - // Process protocol. - //------------------------------------------------------------------ - virtual bool - CanDebug(lldb_private::Target &target, bool plugin_specified_by_name); - - virtual lldb_private::Error - WillLaunch(lldb_private::Module *module); - - virtual lldb_private::Error - DoAttachToProcessWithID(lldb::pid_t pid); - - virtual lldb_private::Error - DoLaunch (lldb_private::Module *exe_module, - const lldb_private::ProcessLaunchInfo &launch_info); - - virtual void - DidLaunch(); - - virtual lldb_private::Error - DoResume(); - - virtual lldb_private::Error - DoHalt(bool &caused_stop); - - virtual lldb_private::Error - DoDetach(); - - virtual lldb_private::Error - DoSignal(int signal); - - virtual lldb_private::Error - DoDestroy(); - - virtual void - RefreshStateAfterStop(); - - virtual bool - IsAlive(); - - virtual size_t - DoReadMemory(lldb::addr_t vm_addr, - void *buf, - size_t size, - lldb_private::Error &error); - - virtual size_t - DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - lldb_private::Error &error); - - virtual lldb::addr_t - DoAllocateMemory(size_t size, uint32_t permissions, - lldb_private::Error &error); - - virtual lldb_private::Error - DoDeallocateMemory(lldb::addr_t ptr); - - virtual size_t - GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site); - - virtual lldb_private::Error - EnableBreakpoint(lldb_private::BreakpointSite *bp_site); - - virtual lldb_private::Error - DisableBreakpoint(lldb_private::BreakpointSite *bp_site); - virtual uint32_t - UpdateThreadListIfNeeded(); - - uint32_t - UpdateThreadList(lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list); - - virtual lldb::ByteOrder - GetByteOrder() const; - - virtual lldb::addr_t - GetImageInfoAddress(); - - virtual size_t - PutSTDIN(const char *buf, size_t len, lldb_private::Error &error); - - virtual size_t - GetSTDOUT(char *buf, size_t len, lldb_private::Error &error); - - virtual size_t - GetSTDERR(char *buf, size_t len, lldb_private::Error &error); - + UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list); //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -165,59 +77,11 @@ EnablePluginLogging(lldb_private::Stream *strm, lldb_private::Args &command); - //-------------------------------------------------------------------------- - // ProcessLinux internal API. - - /// Registers the given message with this process. - void SendMessage(const ProcessMessage &message); - - ProcessMonitor & - GetMonitor() { assert(m_monitor); return *m_monitor; } - - lldb_private::UnixSignals & - GetUnixSignals(); - private: - /// Target byte order. - lldb::ByteOrder m_byte_order; - /// Process monitor; - ProcessMonitor *m_monitor; - - /// The module we are executing. - lldb_private::Module *m_module; - - /// Message queue notifying this instance of inferior process state changes. - lldb_private::Mutex m_message_mutex; - std::queue m_message_queue; - - /// True when the process has entered a state of "limbo". - /// - /// This flag qualifies eStateStopped. It lets us know that when we - /// continue from this state the process will exit. Also, when true, - /// Process::m_exit_status is set. - bool m_in_limbo; - - /// Drive any exit events to completion. - bool m_exit_now; - /// Linux-specific signal set. LinuxSignals m_linux_signals; - /// Updates the loaded sections provided by the executable. - /// - /// FIXME: It would probably be better to delegate this task to the - /// DynamicLoader plugin, when we have one. - void UpdateLoadedSections(); - - /// Returns true if the process has exited. - bool HasExited(); - - /// Returns true if the process is stopped. - bool IsStopped(); - - typedef std::map MMapMap; - MMapMap m_addr_to_mmap_size; }; #endif // liblldb_MacOSXProcess_H_ Index: source/Plugins/Process/Linux/ProcessLinuxLog.h (deleted) =================================================================== Index: source/Plugins/Process/Linux/LinuxStopInfo.cpp (deleted) =================================================================== Index: source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp (deleted) =================================================================== Index: source/Plugins/Process/Linux/ProcessMessage.cpp (deleted) =================================================================== Index: source/Plugins/Process/Linux/LinuxStopInfo.h (deleted) =================================================================== Index: source/Plugins/Process/Linux/ProcessMonitor.cpp =================================================================== --- source/Plugins/Process/Linux/ProcessMonitor.cpp (revision 147532) +++ source/Plugins/Process/Linux/ProcessMonitor.cpp (working copy) @@ -28,9 +28,9 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/PseudoTerminal.h" -#include "LinuxThread.h" +#include "POSIXThread.h" #include "ProcessLinux.h" -#include "ProcessLinuxLog.h" +#include "ProcessPOSIXLog.h" #include "ProcessMonitor.h" @@ -63,8 +63,8 @@ static void PtraceDisplayBytes(__ptrace_request &req, void *data) { StreamString buf; - LogSP verbose_log (ProcessLinuxLog::GetLogIfAllCategoriesSet ( - LINUX_LOG_PTRACE | LINUX_LOG_VERBOSE)); + LogSP verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet ( + POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE)); if (verbose_log) { @@ -120,7 +120,7 @@ { long int result; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PTRACE)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE)); if (log) log->Printf("ptrace(%s, %u, %p, %p) called from file %s line %d", @@ -170,10 +170,10 @@ size_t remainder; long data; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_ALL)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL)); if (log) - ProcessLinuxLog::IncNestLevel(); - if (log && ProcessLinuxLog::AtTopNestLevel() && log->GetMask().Test(LINUX_LOG_MEMORY)) + ProcessPOSIXLog::IncNestLevel(); + if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY)) log->Printf ("ProcessMonitor::%s(%d, %d, %p, %p, %d, _)", __FUNCTION__, pid, word_size, (void*)vm_addr, buf, size); @@ -187,7 +187,7 @@ { error.SetErrorToErrno(); if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_read; } @@ -200,10 +200,10 @@ for (unsigned i = 0; i < remainder; ++i) dst[i] = ((data >> i*8) & 0xFF); - if (log && ProcessLinuxLog::AtTopNestLevel() && - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_LONG) || - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_SHORT) && - size <= LINUX_LOG_MEMORY_SHORT_BYTES))) + if (log && ProcessPOSIXLog::AtTopNestLevel() && + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && + size <= POSIX_LOG_MEMORY_SHORT_BYTES))) log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, (void*)vm_addr, *(unsigned long*)dst, (unsigned long)data); @@ -212,7 +212,7 @@ } if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_read; } @@ -224,10 +224,10 @@ size_t bytes_written = 0; size_t remainder; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_ALL)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL)); if (log) - ProcessLinuxLog::IncNestLevel(); - if (log && ProcessLinuxLog::AtTopNestLevel() && log->GetMask().Test(LINUX_LOG_MEMORY)) + ProcessPOSIXLog::IncNestLevel(); + if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY)) log->Printf ("ProcessMonitor::%s(%d, %d, %p, %p, %d, _)", __FUNCTION__, pid, word_size, (void*)vm_addr, buf, size); @@ -244,10 +244,10 @@ for (unsigned i = 0; i < word_size; ++i) data |= (unsigned long)src[i] << i*8; - if (log && ProcessLinuxLog::AtTopNestLevel() && - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_LONG) || - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_SHORT) && - size <= LINUX_LOG_MEMORY_SHORT_BYTES))) + if (log && ProcessPOSIXLog::AtTopNestLevel() && + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && + size <= POSIX_LOG_MEMORY_SHORT_BYTES))) log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, (void*)vm_addr, *(unsigned long*)src, data); @@ -255,7 +255,7 @@ { error.SetErrorToErrno(); if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } } @@ -266,7 +266,7 @@ buff, word_size, error) != word_size) { if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } @@ -276,14 +276,14 @@ buff, word_size, error) != word_size) { if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } - if (log && ProcessLinuxLog::AtTopNestLevel() && - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_LONG) || - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_SHORT) && - size <= LINUX_LOG_MEMORY_SHORT_BYTES))) + if (log && ProcessPOSIXLog::AtTopNestLevel() && + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && + size <= POSIX_LOG_MEMORY_SHORT_BYTES))) log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, (void*)vm_addr, *(unsigned long*)src, *(unsigned long*)buff); } @@ -292,7 +292,7 @@ src += word_size; } if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } @@ -420,7 +420,7 @@ ReadRegOperation::Execute(ProcessMonitor *monitor) { lldb::pid_t pid = monitor->GetPID(); - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_REGISTERS)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); // Set errno to zero so that we can detect a failed peek. errno = 0; @@ -434,7 +434,7 @@ } if (log) log->Printf ("ProcessMonitor::%s() reg %s: 0x%x", __FUNCTION__, - LinuxThread::GetRegisterNameFromOffset(m_offset), data); + POSIXThread::GetRegisterNameFromOffset(m_offset), data); } //------------------------------------------------------------------------------ @@ -460,7 +460,7 @@ { void* buf; lldb::pid_t pid = monitor->GetPID(); - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_REGISTERS)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); if (sizeof(void*) == sizeof(uint64_t)) buf = (void*) m_value.GetAsUInt64(); @@ -472,7 +472,7 @@ if (log) log->Printf ("ProcessMonitor::%s() reg %s: %p", __FUNCTION__, - LinuxThread::GetRegisterNameFromOffset(m_offset), buf); + POSIXThread::GetRegisterNameFromOffset(m_offset), buf); if (PTRACE(PTRACE_POKEUSER, pid, (void*)m_offset, buf)) m_result = false; else @@ -794,7 +794,7 @@ /// launching or attaching to the inferior process, and then 2) servicing /// operations such as register reads/writes, stepping, etc. See the comments /// on the Operation class for more info as to why this is needed. -ProcessMonitor::ProcessMonitor(ProcessLinux *process, +ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, Module *module, const char *argv[], const char *envp[], @@ -802,7 +802,7 @@ const char *stdout_path, const char *stderr_path, lldb_private::Error &error) - : m_process(process), + : m_process(static_cast(process)), m_operation_thread(LLDB_INVALID_HOST_THREAD), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), @@ -858,10 +858,10 @@ } } -ProcessMonitor::ProcessMonitor(ProcessLinux *process, +ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, lldb::pid_t pid, lldb_private::Error &error) - : m_process(process), + : m_process(static_cast(process)), m_operation_thread(LLDB_INVALID_HOST_THREAD), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), @@ -978,7 +978,7 @@ lldb::pid_t pid; lldb::ThreadSP inferior; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); // Propagate the environment if one is not supplied. if (envp == NULL || envp[0] == NULL) @@ -1105,7 +1105,7 @@ // current. // FIXME: should we be letting UpdateThreadList handle this? // FIXME: by using pids instead of tids, we can only support one thread. - inferior.reset(new LinuxThread(process, pid)); + inferior.reset(new POSIXThread(process, pid)); if (log) log->Printf ("ProcessMonitor::%s() adding pid = %i", __FUNCTION__, pid); process.GetThreadList().AddThread(inferior); @@ -1169,7 +1169,7 @@ ProcessLinux &process = monitor->GetProcess(); lldb::ThreadSP inferior; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); if (pid <= 1) { @@ -1194,12 +1194,14 @@ // Update the process thread list with the attached thread and // mark it as current. - inferior.reset(new LinuxThread(process, pid)); + inferior.reset(new POSIXThread(process, pid)); if (log) log->Printf ("ProcessMonitor::%s() adding tid = %i", __FUNCTION__, pid); process.GetThreadList().AddThread(inferior); +#if 0 + /* recursive self reference in constructor doesn't work very well */ process.GetThreadList().SetSelectedThreadByID(pid); - +#endif // Let our process instance know the thread has stopped. process.SendMessage(ProcessMessage::Trace(pid)); @@ -1568,7 +1570,7 @@ } bool -ProcessMonitor::ReadRegisterValue(unsigned offset, RegisterValue &value) +ProcessMonitor::ReadRegisterValue(unsigned offset, unsigned size, RegisterValue &value) { bool result; ReadRegOperation op(offset, value, result); Index: source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp (deleted) =================================================================== Index: source/Plugins/Process/Linux/RegisterContextLinux_i386.h (deleted) =================================================================== Index: source/Plugins/Process/Linux/LinuxThread.cpp (deleted) =================================================================== Index: source/Plugins/Process/Linux/ProcessMessage.h (deleted) =================================================================== Index: source/Plugins/Process/Linux/ProcessMonitor.h =================================================================== --- source/Plugins/Process/Linux/ProcessMonitor.h (revision 147532) +++ source/Plugins/Process/Linux/ProcessMonitor.h (working copy) @@ -24,10 +24,12 @@ class Error; class Module; class Scalar; + } // End lldb_private namespace. class ProcessLinux; class Operation; +class ProcessPOSIX; /// @class ProcessMonitor /// @brief Manages communication with the inferior (debugee) process. @@ -47,7 +49,7 @@ /// Launches an inferior process ready for debugging. Forms the /// implementation of Process::DoLaunch. - ProcessMonitor(ProcessLinux *process, + ProcessMonitor(ProcessPOSIX *process, lldb_private::Module *module, char const *argv[], char const *envp[], @@ -56,7 +58,7 @@ const char *stderr_path, lldb_private::Error &error); - ProcessMonitor(ProcessLinux *process, + ProcessMonitor(ProcessPOSIX *process, lldb::pid_t pid, lldb_private::Error &error); @@ -104,7 +106,7 @@ /// /// This method is provided for use by RegisterContextLinux derivatives. bool - ReadRegisterValue(unsigned offset, lldb_private::RegisterValue &value); + ReadRegisterValue(unsigned offset, unsigned size, lldb_private::RegisterValue &value); /// Writes the given value to the register identified by the given /// (architecture dependent) offset. Index: source/Plugins/Process/Linux/LinuxThread.h (deleted) =================================================================== Index: source/Plugins/Process/Linux/Makefile =================================================================== --- source/Plugins/Process/Linux/Makefile (revision 147532) +++ source/Plugins/Process/Linux/Makefile (working copy) @@ -12,6 +12,6 @@ BUILD_ARCHIVE = 1 # Extend the include path so we may locate UnwindLLDB.h -CPPFLAGS += -I $(LLDB_LEVEL)/source/Plugins/Utility +CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility include $(LLDB_LEVEL)/Makefile Index: source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h =================================================================== --- source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h (revision 147532) +++ source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h (working copy) @@ -10,67 +10,7 @@ #ifndef liblldb_RegisterContextLinux_x86_64_H_ #define liblldb_RegisterContextLinux_x86_64_H_ -#include "RegisterContextLinux.h" - -class ProcessMonitor; - -class RegisterContextLinux_x86_64 - : public RegisterContextLinux -{ -public: - RegisterContextLinux_x86_64 (lldb_private::Thread &thread, - uint32_t concrete_frame_idx); - - ~RegisterContextLinux_x86_64(); - - void - Invalidate(); - - void - InvalidateAllRegisters(); - - size_t - GetRegisterCount(); - - const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex(uint32_t reg); - - size_t - GetRegisterSetCount(); - - const lldb_private::RegisterSet * - GetRegisterSet(uint32_t set); - - static unsigned - GetRegisterIndexFromOffset(unsigned offset); - - static const char * - GetRegisterName(unsigned reg); - - virtual bool - ReadRegister(const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value); - - bool - ReadAllRegisterValues(lldb::DataBufferSP &data_sp); - - virtual bool - WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value); - - bool - WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); - - uint32_t - ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num); - - bool - HardwareSingleStep(bool enable); - - bool - UpdateAfterBreakpoint(); - - struct GPR +typedef struct _GPR { uint64_t r15; uint64_t r14; @@ -99,67 +39,6 @@ uint64_t es; uint64_t fs; uint64_t gs; - }; + } GPR; - struct MMSReg - { - uint8_t bytes[10]; - uint8_t pad[6]; - }; - - struct XMMReg - { - uint8_t bytes[16]; - }; - - struct FPU - { - uint16_t fcw; - uint16_t fsw; - uint16_t ftw; - uint16_t fop; - uint64_t ip; - uint64_t dp; - uint32_t mxcsr; - uint32_t mxcsrmask; - MMSReg stmm[8]; - XMMReg xmm[16]; - uint32_t padding[24]; - }; - - struct UserArea - { - GPR regs; // General purpose registers. - int32_t fpvalid; // True if FPU is being used. - int32_t pad0; - FPU i387; // FPU registers. - uint64_t tsize; // Text segment size. - uint64_t dsize; // Data segment size. - uint64_t ssize; // Stack segment size. - uint64_t start_code; // VM address of text. - uint64_t start_stack; // VM address of stack bottom (top in rsp). - int64_t signal; // Signal causing core dump. - int32_t reserved; // Unused. - int32_t pad1; - uint64_t ar0; // Location of GPR's. - FPU* fpstate; // Location of FPR's. - uint64_t magic; // Identifier for core dumps. - char u_comm[32]; // Command causing core dump. - uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7). - uint64_t error_code; // CPU error code. - uint64_t fault_address; // Control register CR3. - }; - -private: - UserArea user; - - ProcessMonitor &GetMonitor(); - - bool ReadGPR(); - bool ReadFPR(); - - bool WriteGPR(); - bool WriteFPR(); -}; - -#endif // #ifndef liblldb_RegisterContextLinux_x86_64_H_ +#endif Index: source/Target/Platform.cpp =================================================================== --- source/Target/Platform.cpp (revision 147532) +++ source/Target/Platform.cpp (working copy) @@ -572,34 +572,45 @@ Error &error) { ProcessSP process_sp; - // Make sure we stop at the entry point - launch_info.GetFlags ().Set (eLaunchFlagDebug); - error = LaunchProcess (launch_info); - if (error.Success()) + + if (target->GetPlatform()->CanLaunchViaAttach()) { - if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) + ProcessSP process_sp; + // Make sure we stop at the entry point + launch_info.GetFlags ().Set (eLaunchFlagDebug); + error = LaunchProcess (launch_info); + if (error.Success()) { - ProcessAttachInfo attach_info (launch_info); - process_sp = Attach (attach_info, debugger, target, listener, error); - if (process_sp) + if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) { - // Since we attached to the process, it will think it needs to detach - // if the process object just goes away without an explicit call to - // Process::Kill() or Process::Detach(), so let it know to kill the - // process if this happens. - process_sp->SetShouldDetach (false); - - // If we didn't have any file actions, the pseudo terminal might - // have been used where the slave side was given as the file to - // open for stdin/out/err after we have already opened the master - // so we can read/write stdin/out/err. - int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); - if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) + ProcessAttachInfo attach_info (launch_info); + process_sp = Attach (attach_info, debugger, target, listener, error); + if (process_sp) { - process_sp->SetSTDIOFileDescriptor(pty_fd); + // Since we attached to the process, it will think it needs + // to detach if the process object just goes away without an + // explicit call to Process::Kill() or Process::Detach(), + // so let it know to kill the process if this happens. + process_sp->SetShouldDetach (false); + + // If we didn't have any file actions, the pseudo terminal + // might have been used where the slave side was given as + // the file to open for stdin/out/err after we have already + // opened the master so we can read/write stdin/out/err. + int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); + if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) + { + process_sp->SetSTDIOFileDescriptor(pty_fd); + } } } } + } else { + launch_info.GetFlags().Set(eLaunchFlagDebug); + const char *plugin_name = launch_info.GetProcessPluginName(); + process_sp = target->CreateProcess (listener, plugin_name).get(); + error = process_sp->Launch (launch_info); } + return process_sp; } Index: source/Target/TargetList.cpp =================================================================== --- source/Target/TargetList.cpp (revision 147532) +++ source/Target/TargetList.cpp (working copy) @@ -72,7 +72,8 @@ if (!platform_sp) platform_sp = debugger.GetPlatformList().GetSelectedPlatform (); - ArchSpec arch; + // Unclear why I need to init this and others don't + ArchSpec arch = Host::GetArchitecture(Host::eSystemDefaultArchitecture); if (triple_cstr) { @@ -83,6 +84,7 @@ return error; } } + error = TargetList::CreateTarget (debugger, file, arch, Index: source/lldb.cpp =================================================================== --- source/lldb.cpp (revision 147532) +++ source/lldb.cpp (working copy) @@ -52,13 +52,16 @@ #endif #if defined (__linux__) -#include "Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h" +#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" #include "Plugins/Platform/Linux/PlatformLinux.h" #include "Plugins/Process/Linux/ProcessLinux.h" #endif #if defined (__FreeBSD__) +#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" #include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h" +#include "Plugins/Process/POSIX/ProcessPOSIX.h" +#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h" #endif #include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" @@ -120,10 +123,12 @@ //---------------------------------------------------------------------- PlatformLinux::Initialize(); ProcessLinux::Initialize(); - DynamicLoaderLinuxDYLD::Initialize(); + DynamicLoaderPOSIXDYLD::Initialize(); #endif #if defined (__FreeBSD__) - PlatformFreeBSD::Initialize(); + PlatformFreeBSD::Initialize(); + ProcessFreeBSD::Initialize(); + DynamicLoaderPOSIXDYLD::Initialize(); #endif //---------------------------------------------------------------------- // Platform agnostic plugins @@ -190,11 +195,13 @@ #if defined (__linux__) PlatformLinux::Terminate(); ProcessLinux::Terminate(); - DynamicLoaderLinuxDYLD::Terminate(); + DynamicLoaderPOSIXDYLD::Terminate(); #endif #if defined (__FreeBSD__) - PlatformFreeBSD::Terminate(); + PlatformFreeBSD::Terminate(); + ProcessFreeBSD::Terminate(); + DynamicLoaderPOSIXDYLD::Terminate(); #endif DynamicLoaderStatic::Terminate(); Index: source/Host/linux/Host.cpp =================================================================== --- source/Host/linux/Host.cpp (revision 147532) +++ source/Host/linux/Host.cpp (working copy) @@ -10,12 +10,20 @@ // C Includes #include #include +#include +#include +#include + // C++ Includes // Other libraries and framework includes // Project includes #include "lldb/Core/Error.h" +#include "lldb/Target/Process.h" + #include "lldb/Host/Host.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.h" using namespace lldb; using namespace lldb_private; @@ -43,3 +51,48 @@ return error; } +lldb::DataBufferSP +Host::GetAuxvData(lldb_private::Process *process) +{ + static const size_t path_size = 128; + static char path[path_size]; + lldb::DataBufferSP buf_sp; + + int fd; + + // Ideally, we would simply create a FileSpec and call ReadFileContents. + // However, files in procfs have zero size (since they are, in general, + // dynamically generated by the kernel) which is incompatible with the + // current ReadFileContents implementation. Therefore we simply stream the + // data into a DataBuffer ourselves. + if (snprintf(path, path_size, "/proc/%d/auxv", process->GetID()) < 0) + return buf_sp; + + if ((fd = open(path, O_RDONLY, 0)) < 0) + return buf_sp; + + size_t bytes_read = 0; + std::auto_ptr buf_ap(new DataBufferHeap(1024, 0)); + for (;;) + { + size_t avail = buf_ap->GetByteSize() - bytes_read; + ssize_t status = read(fd, buf_ap->GetBytes() + bytes_read, avail); + + if (status < 0) + break; + + bytes_read += status; + + if (status == 0) + { + buf_ap->SetByteSize(bytes_read); + buf_sp.reset(buf_ap.release()); + break; + } + + if (avail - status == 0) + buf_ap->SetByteSize(2 * buf_ap->GetByteSize()); + } + + return buf_sp; +} Index: source/Host/freebsd/Host.cpp =================================================================== --- source/Host/freebsd/Host.cpp (revision 147532) +++ source/Host/freebsd/Host.cpp (working copy) @@ -9,12 +9,18 @@ // C Includes #include +#include #include #include #include #include #include +#include +#include +#include + + // C++ Includes // Other libraries and framework includes // Project includes @@ -26,15 +32,19 @@ #include "lldb/Core/StreamString.h" #include "lldb/Target/Process.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.h" #include "llvm/Support/Host.h" + extern "C" { - char **environ; + extern char **environ; } using namespace lldb; using namespace lldb_private; + class FreeBSDThread { public: @@ -101,7 +111,7 @@ { char *v; char **var = environ; - for (var = environ; var != NULL; ++var) { + for (; var != NULL && *var != NULL; ++var) { v = strchr(*var, (int)'-'); if (v == NULL) continue; @@ -168,16 +178,14 @@ ProcessInstanceInfo &process_info) { if (process_info.ProcessIDIsValid()) { - int mib[3] = { CTL_KERN, KERN_PROC_ARGS, process_info.GetProcessID() }; + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, process_info.GetProcessID() }; char arg_data[8192]; size_t arg_data_size = sizeof(arg_data); - if (::sysctl (mib, 3, arg_data, &arg_data_size , NULL, 0) == 0) + if (::sysctl (mib, 4, arg_data, &arg_data_size , NULL, 0) == 0) { DataExtractor data (arg_data, arg_data_size, lldb::endian::InlHostByteOrder(), sizeof(void *)); uint32_t offset = 0; - uint32_t start_offset; - uint32_t argc = data.GetU32 (&offset); const char *cstr; cstr = data.GetCStr (&offset); @@ -185,32 +193,34 @@ { process_info.GetExecutableFile().SetFile(cstr, false); - if (match_info_ptr == NULL || + if (!(match_info_ptr == NULL || NameMatches (process_info.GetExecutableFile().GetFilename().GetCString(), match_info_ptr->GetNameMatchType(), - match_info_ptr->GetProcessInfo().GetName())) - { - // Skip NULLs - while (1) - { - const uint8_t *p = data.PeekData(offset, 1); - if ((p == NULL) || (*p != '\0')) - break; - ++offset; - } - // Now extract all arguments - Args &proc_args = process_info.GetArguments(); - for (int i=0; iGetProcessInfo().GetName()))) + return false; + + + Args &proc_args = process_info.GetArguments(); + while (1) + { + const uint8_t *p = data.PeekData(offset, 1); + while ((p != NULL) && (*p == '\0') && offset < arg_data_size) + { + ++offset; + p = data.PeekData(offset, 1); + } + if (p == NULL || offset >= arg_data_size) + return true; + + cstr = data.GetCStr(&offset); + if (cstr) + proc_args.AppendArgument(cstr); + else + return true; + } + } - } + } } return false; } @@ -219,8 +229,8 @@ GetFreeBSDProcessCPUType (ProcessInstanceInfo &process_info) { if (process_info.ProcessIDIsValid()) { - // TODO: This - // return true; + process_info.GetArchitecture() = Host::GetArchitecture (Host::eSystemDefaultArchitecture); + return true; } process_info.GetArchitecture().Clear(); return false; @@ -275,3 +285,46 @@ process_info.Clear(); return false; } + +lldb::DataBufferSP +Host::GetAuxvData(lldb_private::Process *process) +{ + int mib[2] = { CTL_KERN, KERN_PS_STRINGS }; + void *ps_strings_addr, *auxv_addr; + size_t ps_strings_size = sizeof(void *); + Elf_Auxinfo aux_info[AT_COUNT]; + struct ps_strings ps_strings; + struct ptrace_io_desc pid; + DataBufferSP buf_sp; + std::auto_ptr buf_ap(new DataBufferHeap(1024, 0)); + + if (::sysctl(mib, 2, &ps_strings_addr, &ps_strings_size, NULL, 0) == 0) { + pid.piod_op = PIOD_READ_D; + pid.piod_addr = &ps_strings; + pid.piod_offs = ps_strings_addr; + pid.piod_len = sizeof(ps_strings); + if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, NULL)) { + perror("failed to fetch ps_strings"); + buf_ap.release(); + goto done; + } + + auxv_addr = ps_strings.ps_envstr + ps_strings.ps_nenvstr + 1; + + pid.piod_addr = aux_info; + pid.piod_offs = auxv_addr; + pid.piod_len = sizeof(aux_info); + if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, NULL)) { + perror("failed to fetch aux_info"); + buf_ap.release(); + goto done; + } + memcpy(buf_ap->GetBytes(), aux_info, pid.piod_len); + buf_sp.reset(buf_ap.release()); + } else { + perror("sysctl failed on ps_strings"); + } + + done: + return buf_sp; +}