3,465 changes: 3,465 additions & 0 deletions lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp

Large diffs are not rendered by default.

379 changes: 379 additions & 0 deletions lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,379 @@
//===-- NativeProcessLinux.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_NativeProcessLinux_H_
#define liblldb_NativeProcessLinux_H_

// C Includes
#include <semaphore.h>
#include <signal.h>

// C++ Includes
#include <unordered_set>

// Other libraries and framework includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/lldb-types.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Target/MemoryRegionInfo.h"

#include "Host/common/NativeProcessProtocol.h"

namespace lldb_private
{
class Error;
class Module;
class Scalar;

/// @class NativeProcessLinux
/// @brief Manages communication with the inferior (debugee) process.
///
/// Upon construction, this class prepares and launches an inferior process for
/// debugging.
///
/// Changes in the inferior process state are broadcasted.
class NativeProcessLinux: public NativeProcessProtocol
{
public:

// ---------------------------------------------------------------------
// Public Static Methods
// ---------------------------------------------------------------------
static lldb_private::Error
LaunchProcess (
Module *exe_module,
ProcessLaunchInfo &launch_info,
lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
NativeProcessProtocolSP &native_process_sp);

static lldb_private::Error
AttachToProcess (
lldb::pid_t pid,
lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
NativeProcessProtocolSP &native_process_sp);

// ---------------------------------------------------------------------
// Public Instance Methods
// ---------------------------------------------------------------------

~NativeProcessLinux() override;

// ---------------------------------------------------------------------
// NativeProcessProtocol Interface
// ---------------------------------------------------------------------
Error
Resume (const ResumeActionList &resume_actions) override;

Error
Halt () override;

Error
Detach () override;

Error
Signal (int signo) override;

Error
Kill () override;

Error
GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) override;

Error
ReadMemory (lldb::addr_t addr, void *buf, lldb::addr_t size, lldb::addr_t &bytes_read) override;

Error
WriteMemory (lldb::addr_t addr, const void *buf, lldb::addr_t size, lldb::addr_t &bytes_written) override;

Error
AllocateMemory (lldb::addr_t size, uint32_t permissions, lldb::addr_t &addr) override;

Error
DeallocateMemory (lldb::addr_t addr) override;

lldb::addr_t
GetSharedLibraryInfoAddress () override;

size_t
UpdateThreads () override;

bool
GetArchitecture (ArchSpec &arch) const override;

Error
SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override;

void
DoStopIDBumped (uint32_t newBumpId) override;

// ---------------------------------------------------------------------
// Interface used by NativeRegisterContext-derived classes.
// ---------------------------------------------------------------------

/// Reads the contents from the register identified by the given (architecture
/// dependent) offset.
///
/// This method is provided for use by RegisterContextLinux derivatives.
bool
ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
unsigned size, lldb_private::RegisterValue &value);

/// Writes the given value to the register identified by the given
/// (architecture dependent) offset.
///
/// This method is provided for use by RegisterContextLinux derivatives.
bool
WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
const lldb_private::RegisterValue &value);

/// Reads all general purpose registers into the specified buffer.
bool
ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);

/// Reads generic floating point registers into the specified buffer.
bool
ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);

/// Reads the specified register set into the specified buffer.
/// For instance, the extended floating-point register set.
bool
ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);

/// Writes all general purpose registers into the specified buffer.
bool
WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);

/// Writes generic floating point registers into the specified buffer.
bool
WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);

/// Writes the specified register set into the specified buffer.
/// For instance, the extended floating-point register set.
bool
WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);

protected:
// ---------------------------------------------------------------------
// NativeProcessProtocol protected interface
// ---------------------------------------------------------------------
Error
GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) override;

private:

lldb_private::ArchSpec m_arch;

lldb::thread_t m_operation_thread;
lldb::thread_t m_monitor_thread;

// current operation which must be executed on the priviliged thread
void *m_operation;
lldb_private::Mutex m_operation_mutex;

// semaphores notified when Operation is ready to be processed and when
// the operation is complete.
sem_t m_operation_pending;
sem_t m_operation_done;

// Set of tids we're waiting to stop before we notify the delegate of
// the stopped state. We only notify the delegate after all threads
// ordered to stop have signaled their stop.
std::unordered_set<lldb::tid_t> m_wait_for_stop_tids;
lldb_private::Mutex m_wait_for_stop_tids_mutex;

lldb_private::LazyBool m_supports_mem_region;
std::vector<MemoryRegionInfo> m_mem_region_cache;
lldb_private::Mutex m_mem_region_cache_mutex;


struct OperationArgs
{
OperationArgs(NativeProcessLinux *monitor);

~OperationArgs();

NativeProcessLinux *m_monitor; // The monitor performing the attach.
sem_t m_semaphore; // Posted to once operation complete.
lldb_private::Error m_error; // Set if process operation failed.
};

/// @class LauchArgs
///
/// @brief Simple structure to pass data to the thread responsible for
/// launching a child process.
struct LaunchArgs : OperationArgs
{
LaunchArgs(NativeProcessLinux *monitor,
lldb_private::Module *module,
char const **argv,
char const **envp,
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
const char *working_dir);

~LaunchArgs();

lldb_private::Module *m_module; // The executable image to launch.
char const **m_argv; // Process arguments.
char const **m_envp; // Process environment.
const char *m_stdin_path; // Redirect stdin or NULL.
const char *m_stdout_path; // Redirect stdout or NULL.
const char *m_stderr_path; // Redirect stderr or NULL.
const char *m_working_dir; // Working directory or NULL.
};

struct AttachArgs : OperationArgs
{
AttachArgs(NativeProcessLinux *monitor,
lldb::pid_t pid);

~AttachArgs();

lldb::pid_t m_pid; // pid of the process to be attached.
};

// ---------------------------------------------------------------------
// Private Instance Methods
// ---------------------------------------------------------------------
NativeProcessLinux ();

/// Launches an inferior process ready for debugging. Forms the
/// implementation of Process::DoLaunch.
void
LaunchInferior (
Module *module,
char const *argv[],
char const *envp[],
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
const char *working_dir,
Error &error);

/// Attaches to an existing process. Forms the
/// implementation of Process::DoLaunch.
void
AttachToInferior (lldb::pid_t pid, Error &error);

void
StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);

static void *
LaunchOpThread(void *arg);

static bool
Launch(LaunchArgs *args);

void
StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);

static void *
AttachOpThread(void *args);

static bool
Attach(AttachArgs *args);

static bool
SetDefaultPtraceOpts(const lldb::pid_t);

static void
ServeOperation(OperationArgs *args);

static bool
DupDescriptor(const char *path, int fd, int flags);

static bool
MonitorCallback(void *callback_baton,
lldb::pid_t pid, bool exited, int signal, int status);

void
MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid);

void
MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited);

#if 0
static ::ProcessMessage::CrashReason
GetCrashReasonForSIGSEGV(const siginfo_t *info);

static ::ProcessMessage::CrashReason
GetCrashReasonForSIGILL(const siginfo_t *info);

static ::ProcessMessage::CrashReason
GetCrashReasonForSIGFPE(const siginfo_t *info);

static ::ProcessMessage::CrashReason
GetCrashReasonForSIGBUS(const siginfo_t *info);
#endif

void
DoOperation(void *op);

/// Stops the child monitor thread.
void
StopMonitoringChildProcess();

/// Stops the operation thread used to attach/launch a process.
void
StopOpThread();

/// Stops monitoring the child process thread.
void
StopMonitor();

bool
HasThreadNoLock (lldb::tid_t thread_id);

NativeThreadProtocolSP
MaybeGetThreadNoLock (lldb::tid_t thread_id);

bool
StopTrackingThread (lldb::tid_t thread_id);

NativeThreadProtocolSP
AddThread (lldb::tid_t thread_id);

NativeThreadProtocolSP
GetOrCreateThread (lldb::tid_t thread_id, bool &created);

Error
GetSoftwareBreakpointSize (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size);

Error
FixupBreakpointPCAsNeeded (NativeThreadProtocolSP &thread_sp);

/// Writes a siginfo_t structure corresponding to the given thread ID to the
/// memory region pointed to by @p siginfo.
bool
GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err);

/// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
/// corresponding to the given thread ID to the memory pointed to by @p
/// message.
bool
GetEventMessage(lldb::tid_t tid, unsigned long *message);

/// Resumes the given thread. If @p signo is anything but
/// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
bool
Resume(lldb::tid_t tid, uint32_t signo);

/// Single steps the given thread. If @p signo is anything but
/// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
bool
SingleStep(lldb::tid_t tid, uint32_t signo);

lldb_private::Error
Detach(lldb::tid_t tid);
};
} // End lldb_private namespace.

#endif // #ifndef liblldb_NativeProcessLinux_H_
363 changes: 363 additions & 0 deletions lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,363 @@
//===-- NativeThreadLinux.cpp --------------------------------- -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "NativeThreadLinux.h"

#include <signal.h>

#include "NativeProcessLinux.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private-log.h"
#include "Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.h"
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "Plugins/Process/Utility/RegisterInfoInterface.h"

using namespace lldb;
using namespace lldb_private;

namespace
{
void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header)
{
switch (stop_info.reason)
{
case eStopReasonSignal:
log.Printf ("%s: %s: signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
return;
case eStopReasonException:
log.Printf ("%s: %s: exception type 0x%" PRIx64, __FUNCTION__, header, stop_info.details.exception.type);
return;
default:
log.Printf ("%s: %s: invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason));
}
}
}

NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) :
NativeThreadProtocol (process, tid),
m_state (StateType::eStateInvalid),
m_stop_info (),
m_reg_context_sp ()
{
}

const char *
NativeThreadLinux::GetName()
{
NativeProcessProtocolSP process_sp = m_process_wp.lock ();
if (!process_sp)
return "<unknown: no process>";

// const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
return Host::GetThreadName (process_sp->GetID (), GetID ()).c_str ();
}

lldb::StateType
NativeThreadLinux::GetState ()
{
return m_state;
}


bool
NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info)
{
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
switch (m_state)
{
case eStateStopped:
case eStateCrashed:
case eStateExited:
case eStateSuspended:
case eStateUnloaded:
if (log)
LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread: ");
stop_info = m_stop_info;
if (log)
LogThreadStopInfo (*log, stop_info, "returned stop_info: ");
return true;

case eStateInvalid:
case eStateConnected:
case eStateAttaching:
case eStateLaunching:
case eStateRunning:
case eStateStepping:
case eStateDetached:
default:
if (log)
{
log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason",
__FUNCTION__, GetID (), StateAsCString (m_state));
}
return false;
}
}

lldb_private::NativeRegisterContextSP
NativeThreadLinux::GetRegisterContext ()
{
// Return the register context if we already created it.
if (m_reg_context_sp)
return m_reg_context_sp;

// First select the appropriate RegisterInfoInterface.
RegisterInfoInterface *reg_interface = nullptr;
NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
if (!m_process_sp)
return NativeRegisterContextSP ();

ArchSpec target_arch;
if (!m_process_sp->GetArchitecture (target_arch))
return NativeRegisterContextSP ();

switch (target_arch.GetTriple().getOS())
{
case llvm::Triple::Linux:
switch (target_arch.GetMachine())
{
case llvm::Triple::x86:
case llvm::Triple::x86_64:
if (Host::GetArchitecture().GetAddressByteSize() == 4)
{
// 32-bit hosts run with a RegisterContextLinux_i386 context.
reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch));
}
else
{
assert((Host::GetArchitecture ().GetAddressByteSize () == 8) && "Register setting path assumes this is a 64-bit host");
// X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
reg_interface = static_cast<RegisterInfoInterface*> (new RegisterContextLinux_x86_64 (target_arch));
}
break;
default:
break;
}
break;
default:
break;
}

assert(reg_interface && "OS or CPU not supported!");
if (!reg_interface)
return NativeRegisterContextSP ();

// Now create the register context.
switch (target_arch.GetMachine())
{
#if 0
case llvm::Triple::mips64:
{
RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
m_posix_thread = reg_ctx;
m_reg_context_sp.reset(reg_ctx);
break;
}
#endif
#if 0
case llvm::Triple::x86:
#endif
case llvm::Triple::x86_64:
{
const uint32_t concrete_frame_idx = 0;
m_reg_context_sp.reset (new NativeRegisterContextLinux_x86_64(*this, concrete_frame_idx, reg_interface));
break;
}
default:
break;
}

return m_reg_context_sp;
}

Error
NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
{
// TODO implement
return Error ("not implemented");
}

Error
NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
{
// TODO implement
return Error ("not implemented");
}

void
NativeThreadLinux::SetLaunching ()
{
const StateType new_state = StateType::eStateLaunching;
MaybeLogStateChange (new_state);
m_state = new_state;

// Also mark it as stopped since launching temporarily stops the newly created thread
// in the ptrace machinery.
m_stop_info.reason = StopReason::eStopReasonSignal;
m_stop_info.details.signal.signo = SIGSTOP;
}


void
NativeThreadLinux::SetRunning ()
{
const StateType new_state = StateType::eStateRunning;
MaybeLogStateChange (new_state);
m_state = new_state;

m_stop_info.reason = StopReason::eStopReasonNone;
}

void
NativeThreadLinux::SetStepping ()
{
const StateType new_state = StateType::eStateStepping;
MaybeLogStateChange (new_state);
m_state = new_state;

m_stop_info.reason = StopReason::eStopReasonNone;
}

void
NativeThreadLinux::SetStoppedBySignal (uint32_t signo)
{
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
if (log)
log->Printf ("NativeThreadLinux::%s called with signal 0x%" PRIx32, __FUNCTION__, signo);

const StateType new_state = StateType::eStateStopped;
MaybeLogStateChange (new_state);
m_state = new_state;

m_stop_info.reason = StopReason::eStopReasonSignal;
m_stop_info.details.signal.signo = signo;
}

void
NativeThreadLinux::SetStoppedByBreakpoint ()
{
const StateType new_state = StateType::eStateStopped;
MaybeLogStateChange (new_state);
m_state = new_state;

m_stop_info.reason = StopReason::eStopReasonSignal;
m_stop_info.details.signal.signo = SIGTRAP;
}

bool
NativeThreadLinux::IsStoppedAtBreakpoint ()
{
// Are we stopped? If not, this can't be a breakpoint.
if (GetState () != StateType::eStateStopped)
return false;

// Was the stop reason a signal with signal number SIGTRAP? If not, not a breakpoint.
return (m_stop_info.reason == StopReason::eStopReasonSignal) &&
(m_stop_info.details.signal.signo == SIGTRAP);
}

void
NativeThreadLinux::SetCrashedWithException (uint64_t exception_type, lldb::addr_t exception_addr)
{
const StateType new_state = StateType::eStateCrashed;
MaybeLogStateChange (new_state);
m_state = new_state;

m_stop_info.reason = StopReason::eStopReasonException;
m_stop_info.details.exception.type = exception_type;
m_stop_info.details.exception.data_count = 1;
m_stop_info.details.exception.data[0] = exception_addr;
}


void
NativeThreadLinux::SetSuspended ()
{
const StateType new_state = StateType::eStateSuspended;
MaybeLogStateChange (new_state);
m_state = new_state;

// FIXME what makes sense here? Do we need a suspended StopReason?
m_stop_info.reason = StopReason::eStopReasonNone;
}

void
NativeThreadLinux::SetExited ()
{
const StateType new_state = StateType::eStateExited;
MaybeLogStateChange (new_state);
m_state = new_state;

m_stop_info.reason = StopReason::eStopReasonThreadExiting;
}

void
NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
{
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
// If we're not logging, we're done.
if (!log)
return;

// If this is a state change to the same state, we're done.
lldb::StateType old_state = m_state;
if (new_state == old_state)
return;

NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID;

// Log it.
log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
}

static
uint32_t MaybeTranslateHostSignoToGdbSigno (uint32_t host_signo)
{
switch (host_signo)
{
case SIGSEGV: return eGdbSignalBadAccess;
case SIGILL: return eGdbSignalBadInstruction;
case SIGFPE: return eGdbSignalArithmetic;
// NOTE: debugserver sends SIGTRAP through unmodified. Do the same here.
// case SIGTRAP: return eGdbSignalBreakpoint;

// Nothing for eGdbSignalSoftware (0x95).
// Nothing for eGdbSignalEmulation (0x94).

default:
// No translations.
return host_signo;
}
}

uint32_t
NativeThreadLinux::TranslateStopInfoToGdbSignal (const ThreadStopInfo &stop_info) const
{
switch (stop_info.reason)
{
case eStopReasonSignal:
return MaybeTranslateHostSignoToGdbSigno (stop_info.details.signal.signo);
break;

case eStopReasonException:
// FIXME verify how we handle exception type.
return MaybeTranslateHostSignoToGdbSigno (static_cast<uint32_t> (stop_info.details.exception.type));
break;

default:
assert (0 && "unexpected stop_info.reason found");
return 0;
}
}

97 changes: 97 additions & 0 deletions lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//===-- NativeThreadLinux.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_NativeThreadLinux_H_
#define liblldb_NativeThreadLinux_H_

#include "lldb/lldb-private-forward.h"
#include "../../../Host/common/NativeThreadProtocol.h"

namespace lldb_private
{
class NativeProcessLinux;

class NativeThreadLinux : public NativeThreadProtocol
{
friend class NativeProcessLinux;

public:
NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid);

// ---------------------------------------------------------------------
// NativeThreadProtocol Interface
// ---------------------------------------------------------------------
const char *
GetName() override;

lldb::StateType
GetState () override;

bool
GetStopReason (ThreadStopInfo &stop_info) override;

NativeRegisterContextSP
GetRegisterContext () override;

Error
SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override;

Error
RemoveWatchpoint (lldb::addr_t addr) override;

uint32_t
TranslateStopInfoToGdbSignal (const ThreadStopInfo &stop_info) const override;

private:
// ---------------------------------------------------------------------
// Interface for friend classes
// ---------------------------------------------------------------------
void
SetLaunching ();

void
SetRunning ();

void
SetStepping ();

void
SetStoppedBySignal (uint32_t signo);

void
SetStoppedByBreakpoint ();

bool
IsStoppedAtBreakpoint ();

void
SetCrashedWithException (uint64_t exception_type, lldb::addr_t exception_addr);

void
SetSuspended ();

void
SetExited ();

// ---------------------------------------------------------------------
// Private interface
// ---------------------------------------------------------------------
void
MaybeLogStateChange (lldb::StateType new_state);

// ---------------------------------------------------------------------
// Member Variables
// ---------------------------------------------------------------------
lldb::StateType m_state;
ThreadStopInfo m_stop_info;
NativeRegisterContextSP m_reg_context_sp;
};
}

#endif // #ifndef liblldb_NativeThreadLinux_H_
5 changes: 3 additions & 2 deletions lldb/source/Plugins/Process/Linux/ProcessLinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@

// Other libraries and framework includes
#include "lldb/Target/Process.h"
#include "LinuxSignals.h"
#include "ProcessMessage.h"
#include "ProcessPOSIX.h"

#include "Plugins/Process/Utility/LinuxSignals.h"

class ProcessMonitor;

class ProcessLinux :
Expand Down Expand Up @@ -107,7 +108,7 @@ class ProcessLinux :
private:

/// Linux-specific signal set.
LinuxSignals m_linux_signals;
process_linux::LinuxSignals m_linux_signals;

lldb_private::FileSpec *m_core_file;

Expand Down
6 changes: 5 additions & 1 deletion lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1228,8 +1228,12 @@ ProcessMonitor::Launch(LaunchArgs *args)

// Wait for the child process to to trap on its call to execve.
lldb::pid_t wpid;
::pid_t raw_pid;
int status;
if ((wpid = waitpid(pid, &status, 0)) < 0)

raw_pid = waitpid(pid, &status, 0);
wpid = static_cast <lldb::pid_t> (raw_pid);
if (raw_pid < 0)
{
args->m_error.SetErrorToErrno();
goto FINISH;
Expand Down
13 changes: 13 additions & 0 deletions lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -934,3 +934,16 @@ ProcessPOSIX::IsAThreadRunning()
}
return is_running;
}

const DataBufferSP
ProcessPOSIX::GetAuxvData ()
{
// If we're the local platform, we can ask the host for auxv data.
PlatformSP platform_sp = m_target.GetPlatform ();
if (platform_sp && platform_sp->IsHost ())
return lldb_private::Host::GetAuxvData(this);

// Somewhat unexpected - the process is not running locally or we don't have a platform.
assert (false && "no platform or not the host - how did we get here with ProcessPOSIX?");
return DataBufferSP ();
}
3 changes: 3 additions & 0 deletions lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ class ProcessPOSIX :
virtual size_t
PutSTDIN(const char *buf, size_t len, lldb_private::Error &error);

const lldb::DataBufferSP
GetAuxvData () override;

//--------------------------------------------------------------------------
// ProcessPOSIX internal API.

Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/Process/Utility/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ add_lldb_library(lldbPluginProcessUtility
HistoryThread.cpp
HistoryUnwind.cpp
InferiorCallPOSIX.cpp
LinuxSignals.cpp
NativeRegisterContextLinux_x86_64.cpp
RegisterContextDarwin_arm.cpp
RegisterContextDarwin_arm64.cpp
RegisterContextDarwin_i386.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
// Project includes
#include "LinuxSignals.h"

using namespace process_linux;

LinuxSignals::LinuxSignals()
: UnixSignals()
{
Expand All @@ -26,6 +28,10 @@ LinuxSignals::Reset()
{
m_signals.clear();

// FIXME we now need *Signals classes on systems that are different OSes (e.g. LinuxSignals
// needed on MacOSX to debug Linux from MacOSX, and similar scenarios, used by ProcessGDBRemote). These must be defined
// not based on OS includes and defines.

#define ADDSIGNAL(S, SUPPRESS, STOP, NOTIFY, DESCRIPTION) \
AddSignal(SIG ## S, "SIG" #S, #S, SUPPRESS, STOP, NOTIFY, DESCRIPTION)

Expand Down Expand Up @@ -60,9 +66,13 @@ LinuxSignals::Reset()
ADDSIGNAL(VTALRM, false, true, true, "virtual alarm");
ADDSIGNAL(PROF, false, true, true, "profiling alarm");
ADDSIGNAL(WINCH, false, true, true, "window size change");
#ifdef SIGPOLL
ADDSIGNAL(POLL, false, true, true, "pollable event");
#endif
ADDSIGNAL(IO, false, true, true, "input/output ready");
#ifdef SIGPWR
ADDSIGNAL(PWR, false, true, true, "power failure");
#endif
ADDSIGNAL(SYS, false, true, true, "invalid system call");

#undef ADDSIGNAL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,20 @@
// Project includes
#include "lldb/Target/UnixSignals.h"

/// Linux specific set of Unix signals.
class LinuxSignals
: public lldb_private::UnixSignals
namespace process_linux
{
public:
LinuxSignals();

private:
void
Reset();
};
/// Linux specific set of Unix signals.
class LinuxSignals
: public lldb_private::UnixSignals
{
public:
LinuxSignals();

private:
void
Reset();
};
}

#endif
1,040 changes: 1,040 additions & 0 deletions lldb/source/Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.cpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
//===-- NativeRegisterContextLinux_x86_64.h ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#ifndef lldb_NativeRegisterContextLinux_x86_64_h
#define lldb_NativeRegisterContextLinux_x86_64_h

#include "lldb/Target/NativeRegisterContextRegisterInfo.h"
#include "RegisterContext_x86.h"
#include "lldb-x86-register-enums.h"

namespace lldb_private
{
class NativeProcessLinux;

class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextRegisterInfo
{
public:
NativeRegisterContextLinux_x86_64 (NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p);

uint32_t
GetRegisterSetCount () const override;

const RegisterSet *
GetRegisterSet (uint32_t set_index) const override;

Error
ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;

Error
WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;

Error
ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;

Error
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;

private:

// Private member types.
enum FPRType
{
eFPRTypeNotValid = 0,
eFPRTypeFXSAVE,
eFPRTypeXSAVE
};

// Info about register ranges.
struct RegInfo
{
uint32_t num_registers;
uint32_t num_gpr_registers;
uint32_t num_fpr_registers;
uint32_t num_avx_registers;

uint32_t last_gpr;
uint32_t first_fpr;
uint32_t last_fpr;

uint32_t first_st;
uint32_t last_st;
uint32_t first_mm;
uint32_t last_mm;
uint32_t first_xmm;
uint32_t last_xmm;
uint32_t first_ymm;
uint32_t last_ymm;

uint32_t first_dr;
uint32_t gpr_flags;
};

// Private member variables.
mutable FPRType m_fpr_type;
FPR m_fpr;
IOVEC m_iovec;
YMM m_ymm_set;
RegInfo m_reg_info;
uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64];

// Private member methods.
lldb_private::Error
WriteRegister(const uint32_t reg, const RegisterValue &value);

bool IsRegisterSetAvailable (uint32_t set_index) const;

lldb::ByteOrder
GetByteOrder() const;

bool
IsGPR(uint32_t reg_index) const;

FPRType
GetFPRType () const;

bool
IsFPR(uint32_t reg_index) const;

bool
WriteFPR();

bool IsFPR(uint32_t reg_index, FPRType fpr_type) const;

bool
CopyXSTATEtoYMM (uint32_t reg_index, lldb::ByteOrder byte_order);

bool
CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);

bool
IsAVX (uint32_t reg_index) const;

bool
ReadFPR ();

lldb_private::Error
ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value);

bool
ReadGPR();

bool
WriteGPR();
};
}

#endif // #ifndef lldb_NativeRegisterContextLinux_x86_64_h

Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,14 @@ RegisterContextFreeBSD_i386::RegisterContextFreeBSD_i386(const ArchSpec &target_
{
}

RegisterContextFreeBSD_i386::~RegisterContextFreeBSD_i386()
{
}

size_t
RegisterContextFreeBSD_i386::GetGPRSize()
RegisterContextFreeBSD_i386::GetGPRSize() const
{
return sizeof(GPR);
}

const RegisterInfo *
RegisterContextFreeBSD_i386::GetRegisterInfo()
RegisterContextFreeBSD_i386::GetRegisterInfo() const
{
switch (m_target_arch.GetMachine())
{
Expand All @@ -84,3 +80,9 @@ RegisterContextFreeBSD_i386::GetRegisterInfo()
return NULL;
}
}

uint32_t
RegisterContextFreeBSD_i386::GetRegisterCount () const
{
return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ class RegisterContextFreeBSD_i386
{
public:
RegisterContextFreeBSD_i386(const lldb_private::ArchSpec &target_arch);
virtual ~RegisterContextFreeBSD_i386();

size_t
GetGPRSize();
GetGPRSize() const override;

const lldb_private::RegisterInfo *
GetRegisterInfo();
GetRegisterInfo() const override;

uint32_t
GetRegisterCount () const override;
};

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,23 @@ RegisterContextFreeBSD_mips64::RegisterContextFreeBSD_mips64(const ArchSpec &tar
{
}

RegisterContextFreeBSD_mips64::~RegisterContextFreeBSD_mips64()
{
}

size_t
RegisterContextFreeBSD_mips64::GetGPRSize()
RegisterContextFreeBSD_mips64::GetGPRSize() const
{
return sizeof(GPR);
}

const RegisterInfo *
RegisterContextFreeBSD_mips64::GetRegisterInfo()
RegisterContextFreeBSD_mips64::GetRegisterInfo() const
{
assert (m_target_arch.GetCore() == ArchSpec::eCore_mips64);
return g_register_infos_mips64;
}

uint32_t
RegisterContextFreeBSD_mips64::GetRegisterCount () const
{
return static_cast<uint32_t> (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0]));
}


Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ class RegisterContextFreeBSD_mips64:
{
public:
RegisterContextFreeBSD_mips64(const lldb_private::ArchSpec &target_arch);
virtual ~RegisterContextFreeBSD_mips64();

size_t
GetGPRSize();
GetGPRSize() const override;

const lldb_private::RegisterInfo *
GetRegisterInfo();
GetRegisterInfo() const override;

uint32_t
GetRegisterCount () const override;
};

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,17 @@ struct dbreg {
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT

static std::vector<lldb_private::RegisterInfo>&
GetSharedRegisterInfoVector ()
{
static std::vector<lldb_private::RegisterInfo> register_infos;
return register_infos;
}

static const RegisterInfo *
GetRegisterInfo_i386(const lldb_private::ArchSpec& arch)
{
static std::vector<lldb_private::RegisterInfo> g_register_infos;
static std::vector<lldb_private::RegisterInfo> g_register_infos (GetSharedRegisterInfoVector ());

// Allocate RegisterInfo only once
if (g_register_infos.empty())
Expand All @@ -92,33 +99,61 @@ GetRegisterInfo_i386(const lldb_private::ArchSpec& arch)
return &g_register_infos[0];
}

RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(const ArchSpec &target_arch) :
lldb_private::RegisterInfoInterface(target_arch)
static const RegisterInfo *
PrivateGetRegisterInfoPtr (const lldb_private::ArchSpec& target_arch)
{
switch (target_arch.GetMachine())
{
case llvm::Triple::x86:
return GetRegisterInfo_i386 (target_arch);
case llvm::Triple::x86_64:
return g_register_infos_x86_64;
default:
assert(false && "Unhandled target architecture.");
return nullptr;
}
}

RegisterContextFreeBSD_x86_64::~RegisterContextFreeBSD_x86_64()
static uint32_t
PrivateGetRegisterCount (const lldb_private::ArchSpec& target_arch)
{
switch (target_arch.GetMachine())
{
case llvm::Triple::x86:
// This vector should have already been filled.
assert (!GetSharedRegisterInfoVector ().empty () && "i386 register info vector not filled.");
return static_cast<uint32_t> (GetSharedRegisterInfoVector().size ());
case llvm::Triple::x86_64:
return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
default:
assert(false && "Unhandled target architecture.");
return 0;
}
}

RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(const ArchSpec &target_arch) :
lldb_private::RegisterInfoInterface(target_arch),
m_register_info_p (PrivateGetRegisterInfoPtr (target_arch)),
m_register_count (PrivateGetRegisterCount (target_arch))
{
}

size_t
RegisterContextFreeBSD_x86_64::GetGPRSize()
RegisterContextFreeBSD_x86_64::GetGPRSize() const
{
return sizeof(GPR);
}

const RegisterInfo *
RegisterContextFreeBSD_x86_64::GetRegisterInfo()
RegisterContextFreeBSD_x86_64::GetRegisterInfo() const
{
switch (m_target_arch.GetMachine())
{
case llvm::Triple::x86:
return GetRegisterInfo_i386 (m_target_arch);
case llvm::Triple::x86_64:
return g_register_infos_x86_64;
default:
assert(false && "Unhandled target architecture.");
return NULL;
}
return m_register_info_p;
}

uint32_t
RegisterContextFreeBSD_x86_64::GetRegisterCount () const
{
return m_register_count;
}


Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ class RegisterContextFreeBSD_x86_64:
{
public:
RegisterContextFreeBSD_x86_64(const lldb_private::ArchSpec &target_arch);
virtual ~RegisterContextFreeBSD_x86_64();

size_t
GetGPRSize();
GetGPRSize() const override;

const lldb_private::RegisterInfo *
GetRegisterInfo();
GetRegisterInfo() const override;

uint32_t
GetRegisterCount () const override;

private:
const lldb_private::RegisterInfo *m_register_info_p;
const uint32_t m_register_count;
};

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,14 @@ RegisterContextLinux_i386::RegisterContextLinux_i386(const ArchSpec &target_arch
{
}

RegisterContextLinux_i386::~RegisterContextLinux_i386()
{
}

size_t
RegisterContextLinux_i386::GetGPRSize()
RegisterContextLinux_i386::GetGPRSize() const
{
return sizeof(GPR);
}

const RegisterInfo *
RegisterContextLinux_i386::GetRegisterInfo()
RegisterContextLinux_i386::GetRegisterInfo() const
{
switch (m_target_arch.GetMachine())
{
Expand All @@ -122,3 +118,10 @@ RegisterContextLinux_i386::GetRegisterInfo()
return NULL;
}
}

uint32_t
RegisterContextLinux_i386::GetRegisterCount () const
{
return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
}

Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ class RegisterContextLinux_i386
{
public:
RegisterContextLinux_i386(const lldb_private::ArchSpec &target_arch);
virtual ~RegisterContextLinux_i386();

size_t
GetGPRSize();
GetGPRSize() const override;

const lldb_private::RegisterInfo *
GetRegisterInfo();
GetRegisterInfo() const override;

uint32_t
GetRegisterCount () const override;
};

#endif
66 changes: 50 additions & 16 deletions lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,17 @@ struct UserArea
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT

static std::vector<lldb_private::RegisterInfo>&
GetPrivateRegisterInfoVector ()
{
static std::vector<lldb_private::RegisterInfo> g_register_infos;
return g_register_infos;
}

static const RegisterInfo *
GetRegisterInfo_i386(const lldb_private::ArchSpec &arch)
{
static std::vector<lldb_private::RegisterInfo> g_register_infos;
static std::vector<lldb_private::RegisterInfo> g_register_infos (GetPrivateRegisterInfoVector ());

// Allocate RegisterInfo only once
if (g_register_infos.empty())
Expand All @@ -105,33 +112,60 @@ GetRegisterInfo_i386(const lldb_private::ArchSpec &arch)
return &g_register_infos[0];
}

RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
lldb_private::RegisterInfoInterface(target_arch)
static const RegisterInfo *
GetRegisterInfoPtr (const ArchSpec &target_arch)
{
switch (target_arch.GetMachine())
{
case llvm::Triple::x86:
return GetRegisterInfo_i386 (target_arch);
case llvm::Triple::x86_64:
return g_register_infos_x86_64;
default:
assert(false && "Unhandled target architecture.");
return nullptr;
}
}

RegisterContextLinux_x86_64::~RegisterContextLinux_x86_64()
static uint32_t
GetRegisterInfoCount (const ArchSpec &target_arch)
{
switch (target_arch.GetMachine())
{
case llvm::Triple::x86:
{
assert (!GetPrivateRegisterInfoVector ().empty () && "i386 register info not yet filled.");
return static_cast<uint32_t> (GetPrivateRegisterInfoVector ().size ());
}
case llvm::Triple::x86_64:
return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
default:
assert(false && "Unhandled target architecture.");
return 0;
}
}

RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
lldb_private::RegisterInfoInterface(target_arch),
m_register_info_p (GetRegisterInfoPtr (target_arch)),
m_register_info_count (GetRegisterInfoCount (target_arch))
{
}

size_t
RegisterContextLinux_x86_64::GetGPRSize()
RegisterContextLinux_x86_64::GetGPRSize() const
{
return sizeof(GPR);
}

const RegisterInfo *
RegisterContextLinux_x86_64::GetRegisterInfo()
RegisterContextLinux_x86_64::GetRegisterInfo() const
{
switch (m_target_arch.GetMachine())
{
case llvm::Triple::x86:
return GetRegisterInfo_i386 (m_target_arch);
case llvm::Triple::x86_64:
return g_register_infos_x86_64;
default:
assert(false && "Unhandled target architecture.");
return NULL;
}
return m_register_info_p;
}

uint32_t
RegisterContextLinux_x86_64::GetRegisterCount () const
{
return m_register_info_count;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ class RegisterContextLinux_x86_64
{
public:
RegisterContextLinux_x86_64(const lldb_private::ArchSpec &target_arch);
virtual ~RegisterContextLinux_x86_64();

size_t
GetGPRSize();
GetGPRSize() const override;

const lldb_private::RegisterInfo *
GetRegisterInfo();
GetRegisterInfo() const override;

uint32_t
GetRegisterCount () const override;

private:
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
};

#endif
14 changes: 12 additions & 2 deletions lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#ifndef lldb_RegisterInfoInterface_h
#define lldb_RegisterInfoInterface_h

#include "lldb/Core/ArchSpec.h"

namespace lldb_private
{

Expand All @@ -25,12 +27,20 @@ namespace lldb_private
virtual ~RegisterInfoInterface () {}

virtual size_t
GetGPRSize () = 0;
GetGPRSize () const = 0;

virtual const lldb_private::RegisterInfo *
GetRegisterInfo () = 0;
GetRegisterInfo () const = 0;

virtual uint32_t
GetRegisterCount () const = 0;

const lldb_private::ArchSpec&
GetTargetArchitecture() const
{ return m_target_arch; }

public:
// FIXME make private.
lldb_private::ArchSpec m_target_arch;
};

Expand Down
292 changes: 292 additions & 0 deletions lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
//===-- lldb-x86-register-enums.h -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef lldb_x86_register_enums_h
#define lldb_x86_register_enums_h

namespace lldb_private
{

//---------------------------------------------------------------------------
// Internal codes for all i386 registers.
//---------------------------------------------------------------------------
enum
{
k_first_gpr_i386,
gpr_eax_i386 = k_first_gpr_i386,
gpr_ebx_i386,
gpr_ecx_i386,
gpr_edx_i386,
gpr_edi_i386,
gpr_esi_i386,
gpr_ebp_i386,
gpr_esp_i386,
gpr_eip_i386,
gpr_eflags_i386,
gpr_cs_i386,
gpr_fs_i386,
gpr_gs_i386,
gpr_ss_i386,
gpr_ds_i386,
gpr_es_i386,

k_first_alias_i386,
gpr_ax_i386 = k_first_alias_i386,
gpr_bx_i386,
gpr_cx_i386,
gpr_dx_i386,
gpr_di_i386,
gpr_si_i386,
gpr_bp_i386,
gpr_sp_i386,
gpr_ah_i386,
gpr_bh_i386,
gpr_ch_i386,
gpr_dh_i386,
gpr_al_i386,
gpr_bl_i386,
gpr_cl_i386,
gpr_dl_i386,
k_last_alias_i386 = gpr_dl_i386,

k_last_gpr_i386 = k_last_alias_i386,

k_first_fpr_i386,
fpu_fctrl_i386 = k_first_fpr_i386,
fpu_fstat_i386,
fpu_ftag_i386,
fpu_fop_i386,
fpu_fiseg_i386,
fpu_fioff_i386,
fpu_foseg_i386,
fpu_fooff_i386,
fpu_mxcsr_i386,
fpu_mxcsrmask_i386,
fpu_st0_i386,
fpu_st1_i386,
fpu_st2_i386,
fpu_st3_i386,
fpu_st4_i386,
fpu_st5_i386,
fpu_st6_i386,
fpu_st7_i386,
fpu_mm0_i386,
fpu_mm1_i386,
fpu_mm2_i386,
fpu_mm3_i386,
fpu_mm4_i386,
fpu_mm5_i386,
fpu_mm6_i386,
fpu_mm7_i386,
fpu_xmm0_i386,
fpu_xmm1_i386,
fpu_xmm2_i386,
fpu_xmm3_i386,
fpu_xmm4_i386,
fpu_xmm5_i386,
fpu_xmm6_i386,
fpu_xmm7_i386,
k_last_fpr_i386 = fpu_xmm7_i386,

k_first_avx_i386,
fpu_ymm0_i386 = k_first_avx_i386,
fpu_ymm1_i386,
fpu_ymm2_i386,
fpu_ymm3_i386,
fpu_ymm4_i386,
fpu_ymm5_i386,
fpu_ymm6_i386,
fpu_ymm7_i386,
k_last_avx_i386 = fpu_ymm7_i386,

dr0_i386,
dr1_i386,
dr2_i386,
dr3_i386,
dr4_i386,
dr5_i386,
dr6_i386,
dr7_i386,

k_num_registers_i386,
k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1
};

//---------------------------------------------------------------------------
// Internal codes for all x86_64 registers.
//---------------------------------------------------------------------------
enum
{
k_first_gpr_x86_64,
gpr_rax_x86_64 = k_first_gpr_x86_64,
gpr_rbx_x86_64,
gpr_rcx_x86_64,
gpr_rdx_x86_64,
gpr_rdi_x86_64,
gpr_rsi_x86_64,
gpr_rbp_x86_64,
gpr_rsp_x86_64,
gpr_r8_x86_64,
gpr_r9_x86_64,
gpr_r10_x86_64,
gpr_r11_x86_64,
gpr_r12_x86_64,
gpr_r13_x86_64,
gpr_r14_x86_64,
gpr_r15_x86_64,
gpr_rip_x86_64,
gpr_rflags_x86_64,
gpr_cs_x86_64,
gpr_fs_x86_64,
gpr_gs_x86_64,
gpr_ss_x86_64,
gpr_ds_x86_64,
gpr_es_x86_64,

k_first_alias_x86_64,
gpr_eax_x86_64 = k_first_alias_x86_64,
gpr_ebx_x86_64,
gpr_ecx_x86_64,
gpr_edx_x86_64,
gpr_edi_x86_64,
gpr_esi_x86_64,
gpr_ebp_x86_64,
gpr_esp_x86_64,
gpr_r8d_x86_64, // Low 32 bits of r8
gpr_r9d_x86_64, // Low 32 bits of r9
gpr_r10d_x86_64, // Low 32 bits of r10
gpr_r11d_x86_64, // Low 32 bits of r11
gpr_r12d_x86_64, // Low 32 bits of r12
gpr_r13d_x86_64, // Low 32 bits of r13
gpr_r14d_x86_64, // Low 32 bits of r14
gpr_r15d_x86_64, // Low 32 bits of r15
gpr_ax_x86_64,
gpr_bx_x86_64,
gpr_cx_x86_64,
gpr_dx_x86_64,
gpr_di_x86_64,
gpr_si_x86_64,
gpr_bp_x86_64,
gpr_sp_x86_64,
gpr_r8w_x86_64, // Low 16 bits of r8
gpr_r9w_x86_64, // Low 16 bits of r9
gpr_r10w_x86_64, // Low 16 bits of r10
gpr_r11w_x86_64, // Low 16 bits of r11
gpr_r12w_x86_64, // Low 16 bits of r12
gpr_r13w_x86_64, // Low 16 bits of r13
gpr_r14w_x86_64, // Low 16 bits of r14
gpr_r15w_x86_64, // Low 16 bits of r15
gpr_ah_x86_64,
gpr_bh_x86_64,
gpr_ch_x86_64,
gpr_dh_x86_64,
gpr_al_x86_64,
gpr_bl_x86_64,
gpr_cl_x86_64,
gpr_dl_x86_64,
gpr_dil_x86_64,
gpr_sil_x86_64,
gpr_bpl_x86_64,
gpr_spl_x86_64,
gpr_r8l_x86_64, // Low 8 bits of r8
gpr_r9l_x86_64, // Low 8 bits of r9
gpr_r10l_x86_64, // Low 8 bits of r10
gpr_r11l_x86_64, // Low 8 bits of r11
gpr_r12l_x86_64, // Low 8 bits of r12
gpr_r13l_x86_64, // Low 8 bits of r13
gpr_r14l_x86_64, // Low 8 bits of r14
gpr_r15l_x86_64, // Low 8 bits of r15
k_last_alias_x86_64 = gpr_r15l_x86_64,

k_last_gpr_x86_64 = k_last_alias_x86_64,

k_first_fpr_x86_64,
fpu_fctrl_x86_64 = k_first_fpr_x86_64,
fpu_fstat_x86_64,
fpu_ftag_x86_64,
fpu_fop_x86_64,
fpu_fiseg_x86_64,
fpu_fioff_x86_64,
fpu_foseg_x86_64,
fpu_fooff_x86_64,
fpu_mxcsr_x86_64,
fpu_mxcsrmask_x86_64,
fpu_st0_x86_64,
fpu_st1_x86_64,
fpu_st2_x86_64,
fpu_st3_x86_64,
fpu_st4_x86_64,
fpu_st5_x86_64,
fpu_st6_x86_64,
fpu_st7_x86_64,
fpu_mm0_x86_64,
fpu_mm1_x86_64,
fpu_mm2_x86_64,
fpu_mm3_x86_64,
fpu_mm4_x86_64,
fpu_mm5_x86_64,
fpu_mm6_x86_64,
fpu_mm7_x86_64,
fpu_xmm0_x86_64,
fpu_xmm1_x86_64,
fpu_xmm2_x86_64,
fpu_xmm3_x86_64,
fpu_xmm4_x86_64,
fpu_xmm5_x86_64,
fpu_xmm6_x86_64,
fpu_xmm7_x86_64,
fpu_xmm8_x86_64,
fpu_xmm9_x86_64,
fpu_xmm10_x86_64,
fpu_xmm11_x86_64,
fpu_xmm12_x86_64,
fpu_xmm13_x86_64,
fpu_xmm14_x86_64,
fpu_xmm15_x86_64,
k_last_fpr_x86_64 = fpu_xmm15_x86_64,

k_first_avx_x86_64,
fpu_ymm0_x86_64 = k_first_avx_x86_64,
fpu_ymm1_x86_64,
fpu_ymm2_x86_64,
fpu_ymm3_x86_64,
fpu_ymm4_x86_64,
fpu_ymm5_x86_64,
fpu_ymm6_x86_64,
fpu_ymm7_x86_64,
fpu_ymm8_x86_64,
fpu_ymm9_x86_64,
fpu_ymm10_x86_64,
fpu_ymm11_x86_64,
fpu_ymm12_x86_64,
fpu_ymm13_x86_64,
fpu_ymm14_x86_64,
fpu_ymm15_x86_64,
k_last_avx_x86_64 = fpu_ymm15_x86_64,

dr0_x86_64,
dr1_x86_64,
dr2_x86_64,
dr3_x86_64,
dr4_x86_64,
dr5_x86_64,
dr6_x86_64,
dr7_x86_64,

k_num_registers_x86_64,
k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1
};

}

#endif // #ifndef lldb_x86_register_enums_h
2 changes: 1 addition & 1 deletion lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class ProcessElfCore : public lldb_private::Process

// Returns AUXV structure found in the core file
const lldb::DataBufferSP
GetAuxvData();
GetAuxvData() override;

protected:
void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,8 @@ GDBRemoteCommunicationClient::GetGDBServerProgramVersion()
bool
GDBRemoteCommunicationClient::GetHostInfo (bool force)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS));

if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
{
m_qHostInfo_is_valid = eLazyBoolNo;
Expand Down Expand Up @@ -1819,6 +1821,9 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
{
assert (byte_order == m_host_arch.GetByteOrder());
}

if (log)
log->Printf ("GDBRemoteCommunicationClient::%s parsed host architecture as %s, triple as %s from triple text %s", __FUNCTION__, m_host_arch.GetArchitectureName () ? m_host_arch.GetArchitectureName () : "<null-arch-name>", m_host_arch.GetTriple ().getTriple ().c_str(), triple.c_str ());
}
if (!distribution_id.empty ())
m_host_arch.SetDistributionId (distribution_id.c_str ());
Expand Down
4,575 changes: 3,588 additions & 987 deletions lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp

Large diffs are not rendered by default.

198 changes: 192 additions & 6 deletions lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,23 @@
// C++ Includes
#include <vector>
#include <set>
#include <unordered_map>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private-forward.h"
#include "lldb/Core/Communication.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Target/Process.h"
#include "GDBRemoteCommunication.h"

#include "../../../Host/common/NativeProcessProtocol.h"

class ProcessGDBRemote;
class StringExtractorGDBRemote;

class GDBRemoteCommunicationServer : public GDBRemoteCommunication
class GDBRemoteCommunicationServer :
public GDBRemoteCommunication,
public lldb_private::NativeProcessProtocol::NativeDelegate
{
public:
typedef std::map<uint16_t, lldb::pid_t> PortMap;
Expand All @@ -38,12 +45,13 @@ class GDBRemoteCommunicationServer : public GDBRemoteCommunication
GDBRemoteCommunicationServer(bool is_platform);

GDBRemoteCommunicationServer(bool is_platform,
const lldb::PlatformSP& platform_sp);
const lldb::PlatformSP& platform_sp,
lldb::DebuggerSP& debugger_sp);

virtual
~GDBRemoteCommunicationServer();

bool
PacketResult
GetPacketAndSendResponse (uint32_t timeout_usec,
lldb_private::Error &error,
bool &interrupt,
Expand Down Expand Up @@ -188,6 +196,28 @@ class GDBRemoteCommunicationServer : public GDBRemoteCommunication
lldb_private::Error
LaunchProcess ();

//------------------------------------------------------------------
/// Attach to a process.
///
/// This method supports attaching llgs to a process accessible via the
/// configured Platform.
///
/// @return
/// An Error object indicating the success or failure of the
/// attach operation.
//------------------------------------------------------------------
lldb_private::Error
AttachToProcess (lldb::pid_t pid);

//------------------------------------------------------------------
// NativeProcessProtocol::NativeDelegate overrides
//------------------------------------------------------------------
void
InitializeDelegate (lldb_private::NativeProcessProtocol *process) override;

void
ProcessStateChanged (lldb_private::NativeProcessProtocol *process, lldb::StateType state) override;

protected:
lldb::PlatformSP m_platform_sp;
lldb::thread_t m_async_thread;
Expand All @@ -199,17 +229,45 @@ class GDBRemoteCommunicationServer : public GDBRemoteCommunication
uint32_t m_proc_infos_index;
PortMap m_port_map;
uint16_t m_port_offset;

lldb::tid_t m_current_tid;
lldb::tid_t m_continue_tid;
lldb_private::Mutex m_debugged_process_mutex;
lldb_private::NativeProcessProtocolSP m_debugged_process_sp;
lldb::DebuggerSP m_debugger_sp;
Communication m_stdio_communication;
bool m_exit_now; // use in asynchronous handling to indicate process should exit.
lldb::StateType m_inferior_prev_state;
bool m_thread_suffix_supported;
bool m_list_threads_in_stop_reply;
lldb::DataBufferSP m_active_auxv_buffer_sp;
lldb_private::Mutex m_saved_registers_mutex;
std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
uint32_t m_next_saved_registers_id;

PacketResult
SendUnimplementedResponse (const char *packet);

PacketResult
SendErrorResponse (uint8_t error);

PacketResult
SendIllFormedResponse (const StringExtractorGDBRemote &packet, const char *error_message);

PacketResult
SendOKResponse ();

PacketResult
SendONotification (const char *buffer, uint32_t len);

PacketResult
SendWResponse (lldb_private::NativeProcessProtocol *process);

PacketResult
SendStopReplyPacketForThread (lldb::tid_t tid);

PacketResult
SendStopReasonForState (lldb::StateType process_state, bool flush_on_exit);

PacketResult
Handle_A (StringExtractorGDBRemote &packet);

Expand All @@ -233,7 +291,10 @@ class GDBRemoteCommunicationServer : public GDBRemoteCommunication

PacketResult
Handle_qPlatform_chmod (StringExtractorGDBRemote &packet);


PacketResult
Handle_qProcessInfo (StringExtractorGDBRemote &packet);

PacketResult
Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);

Expand Down Expand Up @@ -284,7 +345,22 @@ class GDBRemoteCommunicationServer : public GDBRemoteCommunication

PacketResult
Handle_QSetSTDERR (StringExtractorGDBRemote &packet);


PacketResult
Handle_C (StringExtractorGDBRemote &packet);

PacketResult
Handle_c (StringExtractorGDBRemote &packet, bool skip_file_pos_adjustment = false);

PacketResult
Handle_vCont (StringExtractorGDBRemote &packet);

PacketResult
Handle_vCont_actions (StringExtractorGDBRemote &packet);

PacketResult
Handle_stop_reason (StringExtractorGDBRemote &packet);

PacketResult
Handle_vFile_Open (StringExtractorGDBRemote &packet);

Expand Down Expand Up @@ -321,6 +397,84 @@ class GDBRemoteCommunicationServer : public GDBRemoteCommunication
PacketResult
Handle_qPlatform_shell (StringExtractorGDBRemote &packet);

PacketResult
Handle_qRegisterInfo (StringExtractorGDBRemote &packet);

PacketResult
Handle_qfThreadInfo (StringExtractorGDBRemote &packet);

PacketResult
Handle_qsThreadInfo (StringExtractorGDBRemote &packet);

PacketResult
Handle_p (StringExtractorGDBRemote &packet);

PacketResult
Handle_P (StringExtractorGDBRemote &packet);

PacketResult
Handle_H (StringExtractorGDBRemote &packet);

PacketResult
Handle_interrupt (StringExtractorGDBRemote &packet);

PacketResult
Handle_m (StringExtractorGDBRemote &packet);

PacketResult
Handle_M (StringExtractorGDBRemote &packet);

PacketResult
Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet);

PacketResult
Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet);

PacketResult
Handle_Z (StringExtractorGDBRemote &packet);

PacketResult
Handle_z (StringExtractorGDBRemote &packet);

PacketResult
Handle_s (StringExtractorGDBRemote &packet);

PacketResult
Handle_qSupported (StringExtractorGDBRemote &packet);

PacketResult
Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet);

PacketResult
Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet);

PacketResult
Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet);

PacketResult
Handle_QSaveRegisterState (StringExtractorGDBRemote &packet);

PacketResult
Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet);

void
SetCurrentThreadID (lldb::tid_t tid);

lldb::tid_t
GetCurrentThreadID () const;

void
SetContinueThreadID (lldb::tid_t tid);

lldb::tid_t
GetContinueThreadID () const { return m_continue_tid; }

lldb_private::Error
SetSTDIOFileDescriptor (int fd);

static void
STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);

private:
bool
DebugserverProcessReaped (lldb::pid_t pid);
Expand All @@ -345,6 +499,38 @@ class GDBRemoteCommunicationServer : public GDBRemoteCommunication
bool
KillSpawnedProcess (lldb::pid_t pid);

bool
IsGdbServer ()
{
return !m_is_platform;
}

/// Launch a process from lldb-gdbserver
lldb_private::Error
LaunchDebugServerProcess ();

/// Launch a process from lldb-platform
lldb_private::Error
LaunchPlatformProcess ();

void
HandleInferiorState_Exited (lldb_private::NativeProcessProtocol *process);

void
HandleInferiorState_Stopped (lldb_private::NativeProcessProtocol *process);

void
FlushInferiorOutput ();

lldb_private::NativeThreadProtocolSP
GetThreadFromSuffix (StringExtractorGDBRemote &packet);

uint32_t
GetNextSavedRegistersID ();

void
MaybeCloseInferiorTerminalConnection ();

//------------------------------------------------------------------
// For GDBRemoteCommunicationServer only
//------------------------------------------------------------------
Expand Down
60 changes: 58 additions & 2 deletions lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@

// Project includes
#include "lldb/Host/Host.h"
#include "Plugins/Process/Utility/FreeBSDSignals.h"
#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
#include "Plugins/Process/Utility/LinuxSignals.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#include "Utility/StringExtractorGDBRemote.h"
Expand Down Expand Up @@ -285,7 +287,8 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
m_waiting_for_attach (false),
m_destroy_tried_resuming (false),
m_command_sp (),
m_breakpoint_pc_offset (0)
m_breakpoint_pc_offset (0),
m_unix_signals_sp (new UnixSignals ())
{
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
Expand Down Expand Up @@ -628,6 +631,7 @@ ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wa
Error
ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Error error (WillLaunchOrAttach ());

if (error.Fail())
Expand Down Expand Up @@ -678,7 +682,11 @@ ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
}

if (error.Success()
if (log)
log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalizing target architecture initial triple: %s (GetTarget().GetArchitecture().IsValid() %s, m_gdb_comm.GetHostArchitecture().IsValid(): %s)", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str (), GetTarget ().GetArchitecture ().IsValid () ? "true" : "false", m_gdb_comm.GetHostArchitecture ().IsValid () ? "true" : "false");


if (error.Success()
&& !GetTarget().GetArchitecture().IsValid()
&& m_gdb_comm.GetHostArchitecture().IsValid())
{
Expand All @@ -689,6 +697,42 @@ ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
}

if (log)
log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalized target architecture triple: %s", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str ());

// Set the Unix signals properly for the target.
// FIXME Add a gdb-remote packet to discover dynamically.
if (error.Success ())
{
const ArchSpec arch_spec = GetTarget ().GetArchitecture ();
if (arch_spec.IsValid ())
{
if (log)
log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": determining unix signals type based on architecture %s, triple %s", __FUNCTION__, GetID (), arch_spec.GetArchitectureName () ? arch_spec.GetArchitectureName () : "<null>", arch_spec.GetTriple ().getTriple ().c_str ());

switch (arch_spec.GetTriple ().getOS ())
{
case llvm::Triple::Linux:
m_unix_signals_sp.reset (new process_linux::LinuxSignals ());
if (log)
log->Printf ("ProcessGDBRemote::%s using Linux unix signals type for pid %" PRIu64, __FUNCTION__, GetID ());
break;
case llvm::Triple::OpenBSD:
case llvm::Triple::FreeBSD:
case llvm::Triple::NetBSD:
m_unix_signals_sp.reset (new FreeBSDSignals ());
if (log)
log->Printf ("ProcessGDBRemote::%s using *BSD unix signals type for pid %" PRIu64, __FUNCTION__, GetID ());
break;
default:
m_unix_signals_sp.reset (new UnixSignals ());
if (log)
log->Printf ("ProcessGDBRemote::%s using generic unix signals type for pid %" PRIu64, __FUNCTION__, GetID ());
break;
}
}
}

return error;
}

Expand Down Expand Up @@ -1040,6 +1084,13 @@ ProcessGDBRemote::DidLaunch ()
DidLaunchOrAttach ();
}

UnixSignals&
ProcessGDBRemote::GetUnixSignals ()
{
assert (m_unix_signals_sp && "m_unix_signals_sp is null");
return *m_unix_signals_sp;
}

Error
ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid)
{
Expand Down Expand Up @@ -2231,6 +2282,7 @@ ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Erro
lldb::addr_t
ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
{
lldb_private::Log *log (lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_EXPRESSIONS));
addr_t allocated_addr = LLDB_INVALID_ADDRESS;

LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
Expand All @@ -2256,7 +2308,11 @@ ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &er
eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0))
m_addr_to_mmap_size[allocated_addr] = size;
else
{
allocated_addr = LLDB_INVALID_ADDRESS;
if (log)
log->Printf ("ProcessGDBRemote::%s no direct stub support for memory allocation, and InferiorCallMmap also failed - is stub missing register context save/restore capability?", __FUNCTION__);
}
break;
}

Expand Down
11 changes: 8 additions & 3 deletions lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ class ProcessGDBRemote : public lldb_private::Process
virtual void
DidLaunch ();

lldb_private::UnixSignals&
GetUnixSignals () override;

virtual lldb_private::Error
WillAttachToProcessWithID (lldb::pid_t pid);

Expand Down Expand Up @@ -305,8 +308,8 @@ class ProcessGDBRemote : public lldb_private::Process
bool
ParseRegisters(lldb_private::ScriptInterpreterObject *registers_array);

virtual const lldb::DataBufferSP
GetAuxvData();
const lldb::DataBufferSP
GetAuxvData() override;

lldb_private::StructuredData::ObjectSP
GetExtendedInfoForThread (lldb::tid_t tid);
Expand Down Expand Up @@ -357,7 +360,9 @@ class ProcessGDBRemote : public lldb_private::Process
bool m_destroy_tried_resuming;
lldb::CommandObjectSP m_command_sp;
int64_t m_breakpoint_pc_offset;

std::shared_ptr<lldb_private::UnixSignals> m_unix_signals_sp;


bool
StartAsyncThread ();

Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Target/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ add_lldb_library(lldbTarget
JITLoaderList.cpp
LanguageRuntime.cpp
Memory.cpp
NativeRegisterContext.cpp
NativeRegisterContextRegisterInfo.cpp
ObjCLanguageRuntime.cpp
OperatingSystem.cpp
PathMappingList.cpp
Expand Down
470 changes: 470 additions & 0 deletions lldb/source/Target/NativeRegisterContext.cpp

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions lldb/source/Target/NativeRegisterContextRegisterInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===-- NativeRegisterContex.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-types.h"
#include "lldb/lldb-private-forward.h"
#include "lldb/Target/NativeRegisterContextRegisterInfo.h"

using namespace lldb_private;

NativeRegisterContextRegisterInfo::NativeRegisterContextRegisterInfo (NativeThreadProtocol &thread,
uint32_t concrete_frame_idx,
RegisterInfoInterface *register_info_interface) :
NativeRegisterContext (thread, concrete_frame_idx),
m_register_info_interface_up (register_info_interface)
{
assert (register_info_interface && "null register_info_interface");
}

uint32_t
NativeRegisterContextRegisterInfo::GetRegisterCount () const
{
return m_register_info_interface_up->GetRegisterCount ();
}

const RegisterInfo *
NativeRegisterContextRegisterInfo::GetRegisterInfoAtIndex (uint32_t reg_index) const
{
if (reg_index <= GetRegisterCount ())
return m_register_info_interface_up->GetRegisterInfo () + reg_index;
else
return nullptr;
}

const RegisterInfoInterface&
NativeRegisterContextRegisterInfo::GetRegisterInfoInterface () const
{
return *m_register_info_interface_up;
}
25 changes: 22 additions & 3 deletions lldb/source/Target/Platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,12 +527,10 @@ RecurseCopy_Callback (void *baton,
case FileSpec::eFileTypeInvalid:
case FileSpec::eFileTypeOther:
case FileSpec::eFileTypeUnknown:
default:
rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s", src.GetPath().c_str());
return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
break;
default:
return FileSpec::eEnumerateDirectoryResultQuit; // unsupported file type, bail out
break;
}
}

Expand Down Expand Up @@ -1189,6 +1187,27 @@ Platform::CalculateMD5 (const FileSpec& file_spec,
return false;
}

Error
Platform::LaunchNativeProcess (
ProcessLaunchInfo &launch_info,
lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
NativeProcessProtocolSP &process_sp)
{
// Platforms should override this implementation if they want to
// support lldb-gdbserver.
return Error("unimplemented");
}

Error
Platform::AttachNativeProcess (lldb::pid_t pid,
lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
NativeProcessProtocolSP &process_sp)
{
// Platforms should override this implementation if they want to
// support lldb-gdbserver.
return Error("unimplemented");
}

void
Platform::SetLocalCacheDirectory (const char* local)
{
Expand Down
15 changes: 15 additions & 0 deletions lldb/source/Target/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2529,16 +2529,25 @@ Process::CanJIT ()
{
if (m_can_jit == eCanJITDontKnow)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Error err;

uint64_t allocated_memory = AllocateMemory(8,
ePermissionsReadable | ePermissionsWritable | ePermissionsExecutable,
err);

if (err.Success())
{
m_can_jit = eCanJITYes;
if (log)
log->Printf ("Process::%s pid %" PRIu64 " allocation test passed, CanJIT () is true", __FUNCTION__, GetID ());
}
else
{
m_can_jit = eCanJITNo;
if (log)
log->Printf ("Process::%s pid %" PRIu64 " allocation test failed, CanJIT () is false: %s", __FUNCTION__, GetID (), err.AsCString ());
}

DeallocateMemory (allocated_memory);
}
Expand Down Expand Up @@ -2788,6 +2797,12 @@ Process::GetDynamicLoader ()
return m_dyld_ap.get();
}

const lldb::DataBufferSP
Process::GetAuxvData()
{
return DataBufferSP ();
}

JITLoaderList &
Process::GetJITLoaders ()
{
Expand Down
13 changes: 13 additions & 0 deletions lldb/source/Utility/StringExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,18 @@ StringExtractor::GetHexByteString (std::string &str)
return str.size();
}

size_t
StringExtractor::GetHexByteStringFixedLength (std::string &str, uint32_t nibble_length)
{
str.clear();

uint32_t nibble_count = 0;
for (const char *pch = Peek(); (nibble_count < nibble_length) && (pch != nullptr); str.append(1, GetHexU8(0, false)), pch = Peek (), nibble_count += 2)
{}

return str.size();
}

size_t
StringExtractor::GetHexByteStringTerminatedBy (std::string &str,
char terminator)
Expand All @@ -428,6 +440,7 @@ StringExtractor::GetHexByteStringTerminatedBy (std::string &str,
str.append(1, ch);
if (Peek() && *Peek() == terminator)
return str.size();

str.clear();
return str.size();
}
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Utility/StringExtractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ class StringExtractor
size_t
GetHexByteString (std::string &str);

size_t
GetHexByteStringFixedLength (std::string &str, uint32_t nibble_length);

size_t
GetHexByteStringTerminatedBy (std::string &str,
char terminator);
Expand Down
5 changes: 5 additions & 0 deletions lldb/source/Utility/StringExtractorGDBRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ StringExtractorGDBRemote::GetServerPacketType () const
if (PACKET_STARTS_WITH ("qSpeedTest:")) return eServerPacketType_qSpeedTest;
if (PACKET_MATCHES ("qShlibInfoAddr")) return eServerPacketType_qShlibInfoAddr;
if (PACKET_MATCHES ("qStepPacketSupported")) return eServerPacketType_qStepPacketSupported;
if (PACKET_STARTS_WITH ("qSupported")) return eServerPacketType_qSupported;
if (PACKET_MATCHES ("qSyncThreadStateSupported")) return eServerPacketType_qSyncThreadStateSupported;
break;

Expand All @@ -199,6 +200,10 @@ StringExtractorGDBRemote::GetServerPacketType () const
if (PACKET_STARTS_WITH ("qWatchpointSupportInfo:")) return eServerPacketType_qWatchpointSupportInfo;
if (PACKET_MATCHES ("qWatchpointSupportInfo")) return eServerPacketType_qWatchpointSupportInfoSupported;
break;

case 'X':
if (PACKET_STARTS_WITH ("qXfer:auxv:read::")) return eServerPacketType_qXfer_auxv_read;
break;
}
break;
case 'v':
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Utility/StringExtractorGDBRemote.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,14 @@ class StringExtractorGDBRemote : public StringExtractor
eServerPacketType_qRegisterInfo,
eServerPacketType_qShlibInfoAddr,
eServerPacketType_qStepPacketSupported,
eServerPacketType_qSupported,
eServerPacketType_qSyncThreadStateSupported,
eServerPacketType_qThreadExtraInfo,
eServerPacketType_qThreadStopInfo,
eServerPacketType_qVAttachOrWaitSupported,
eServerPacketType_qWatchpointSupportInfo,
eServerPacketType_qWatchpointSupportInfoSupported,
eServerPacketType_qXfer_auxv_read,

eServerPacketType_vAttach,
eServerPacketType_vAttachWait,
Expand Down
4 changes: 0 additions & 4 deletions lldb/test/tools/lldb-gdbserver/TestGdbRemoteAuxvSupport.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ def supports_auxv(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_supports_auxv_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -111,7 +110,6 @@ def test_auxv_data_is_correct_size_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_auxv_data_is_correct_size_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -152,7 +150,6 @@ def test_auxv_keys_look_valid_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_auxv_keys_look_valid_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -200,7 +197,6 @@ def test_auxv_chunked_reads_work_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_auxv_chunked_reads_work_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ def test_stop_notification_contains_any_registers_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_stop_notification_contains_any_registers_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -87,7 +86,6 @@ def test_stop_notification_contains_no_duplicate_registers_debugserver_dsym(self

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_stop_notification_contains_no_duplicate_registers_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -107,7 +105,6 @@ def test_stop_notification_contains_pc_register_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_stop_notification_contains_pc_register_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -127,7 +124,6 @@ def test_stop_notification_contains_fp_register_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_stop_notification_contains_fp_register_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -147,7 +143,6 @@ def test_stop_notification_contains_sp_register_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_stop_notification_contains_sp_register_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down
2 changes: 0 additions & 2 deletions lldb/test/tools/lldb-gdbserver/TestGdbRemoteRegisterState.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ def test_grp_register_save_restore_works_with_suffix_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_grp_register_save_restore_works_with_suffix_llgs_dwarf(self):
USE_THREAD_SUFFIX = True
self.init_llgs_test()
Expand All @@ -119,7 +118,6 @@ def test_grp_register_save_restore_works_no_suffix_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_grp_register_save_restore_works_no_suffix_llgs_dwarf(self):
USE_THREAD_SUFFIX = False
self.init_llgs_test()
Expand Down
1 change: 0 additions & 1 deletion lldb/test/tools/lldb-gdbserver/TestGdbRemoteSingleStep.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ def test_single_step_only_steps_one_instruction_with_s_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_single_step_only_steps_one_instruction_with_s_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ def test_QListThreadsInStopReply_supported_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_QListThreadsInStopReply_supported_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -105,7 +104,6 @@ def test_stop_reply_reports_multiple_threads_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_stop_reply_reports_multiple_threads_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -127,8 +125,7 @@ def test_no_QListThreadsInStopReply_supplies_no_threads_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_no_QThreadsInStopReply_supplies_no_threads_llgs_dwarf(self):
def test_no_QListThreadsInStopReply_supplies_no_threads_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
self.set_inferior_startup_launch()
Expand Down Expand Up @@ -164,7 +161,6 @@ def test_stop_reply_reports_correct_threads_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_stop_reply_reports_correct_threads_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down
9 changes: 0 additions & 9 deletions lldb/test/tools/lldb-gdbserver/TestGdbRemote_vCont.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ def test_vCont_supports_c_debugserver_dsym(self):
self.vCont_supports_c()

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_vCont_supports_c_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -57,7 +55,6 @@ def test_vCont_supports_C_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_vCont_supports_C_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -72,7 +69,6 @@ def test_vCont_supports_s_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_vCont_supports_s_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -87,7 +83,6 @@ def test_vCont_supports_S_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_vCont_supports_S_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -103,7 +98,6 @@ def test_single_step_only_steps_one_instruction_with_Hc_vCont_s_debugserver_dsym

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_single_step_only_steps_one_instruction_with_Hc_vCont_s_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -120,15 +114,12 @@ def test_single_step_only_steps_one_instruction_with_vCont_s_thread_debugserver_

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_single_step_only_steps_one_instruction_with_vCont_s_thread_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
self.set_inferior_startup_launch()
self.single_step_only_steps_one_instruction(use_Hc_packet=False, step_instruction="vCont;s:{thread}")




if __name__ == '__main__':
unittest2.main()
37 changes: 0 additions & 37 deletions lldb/test/tools/lldb-gdbserver/TestLldbGdbServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def test_thread_suffix_supported_debugserver(self):
self.thread_suffix_supported()

@llgs_test
@unittest2.expectedFailure()
def test_thread_suffix_supported_llgs(self):
self.init_llgs_test()
self.thread_suffix_supported()
Expand All @@ -85,7 +84,6 @@ def test_list_threads_in_stop_reply_supported_debugserver(self):
self.list_threads_in_stop_reply_supported()

@llgs_test
@unittest2.expectedFailure()
def test_list_threads_in_stop_reply_supported_llgs(self):
self.init_llgs_test()
self.list_threads_in_stop_reply_supported()
Expand Down Expand Up @@ -143,7 +141,6 @@ def test_inferior_exit_0_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_inferior_exit_0_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -176,7 +173,6 @@ def test_inferior_exit_42_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_inferior_exit_42_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -207,7 +203,6 @@ def test_c_packet_works_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_c_packet_works_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -240,7 +235,6 @@ def test_inferior_print_exit_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_inferior_print_exit_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -272,7 +266,6 @@ def test_first_launch_stop_reply_thread_matches_first_qC_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_first_launch_stop_reply_thread_matches_first_qC_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -308,7 +301,6 @@ def test_qProcessInfo_returns_running_process_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qProcessInfo_returns_running_process_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -343,7 +335,6 @@ def test_attach_commandline_qProcessInfo_reports_correct_pid_debugserver_dsym(se

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_attach_commandline_qProcessInfo_reports_correct_pid_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -376,7 +367,6 @@ def test_qProcessInfo_reports_valid_endian_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qProcessInfo_reports_valid_endian_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -410,7 +400,6 @@ def test_attach_commandline_continue_app_exits_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_attach_commandline_continue_app_exits_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -445,7 +434,6 @@ def test_attach_commandline_kill_after_initial_stop_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_attach_commandline_kill_after_initial_stop_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -484,7 +472,6 @@ def test_qRegisterInfo_returns_one_valid_result_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qRegisterInfo_returns_one_valid_result_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -519,7 +506,6 @@ def test_qRegisterInfo_returns_all_valid_results_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qRegisterInfo_returns_all_valid_results_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -568,7 +554,6 @@ def test_qRegisterInfo_contains_required_generics_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qRegisterInfo_contains_required_generics_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -606,7 +591,6 @@ def test_qRegisterInfo_contains_at_least_one_register_set_debugserver_dsym(self)

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qRegisterInfo_contains_at_least_one_register_set_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -635,10 +619,8 @@ def qRegisterInfo_contains_avx_registers_on_linux_x86_64(self):
register_sets = { reg_info['set']:1 for reg_info in reg_infos if 'set' in reg_info }
self.assertTrue("Advanced Vector Extensions" in register_sets)


@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qRegisterInfo_contains_avx_registers_on_linux_x86_64_llgs_dwarf(self):
# Skip this test if not Linux x86_64.
if platform.system() != "Linux" or platform.processor() != "x86_64":
Expand Down Expand Up @@ -673,7 +655,6 @@ def test_qThreadInfo_contains_thread_launch_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qThreadInfo_contains_thread_launch_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -690,7 +671,6 @@ def test_qThreadInfo_contains_thread_attach_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qThreadInfo_contains_thread_attach_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -735,7 +715,6 @@ def test_qThreadInfo_matches_qC_launch_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qThreadInfo_matches_qC_launch_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -752,7 +731,6 @@ def test_qThreadInfo_matches_qC_attach_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qThreadInfo_matches_qC_attach_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -810,7 +788,6 @@ def test_p_returns_correct_data_size_for_each_qRegisterInfo_launch_debugserver_d

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_p_returns_correct_data_size_for_each_qRegisterInfo_launch_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -827,7 +804,6 @@ def test_p_returns_correct_data_size_for_each_qRegisterInfo_attach_debugserver_d

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_p_returns_correct_data_size_for_each_qRegisterInfo_attach_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -873,7 +849,6 @@ def test_Hg_switches_to_3_threads_launch_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_Hg_switches_to_3_threads_launch_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand All @@ -890,7 +865,6 @@ def test_Hg_switches_to_3_threads_attach_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_Hg_switches_to_3_threads_attach_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1010,7 +984,6 @@ def test_Hc_then_Csignal_signals_correct_thread_launch_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_Hc_then_Csignal_signals_correct_thread_launch_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1073,7 +1046,6 @@ def test_m_packet_reads_memory_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_m_packet_reads_memory_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1101,7 +1073,6 @@ def test_qMemoryRegionInfo_is_supported_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qMemoryRegionInfo_is_supported_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1165,7 +1136,6 @@ def test_qMemoryRegionInfo_reports_code_address_as_executable_debugserver_dsym(s

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qMemoryRegionInfo_reports_code_address_as_executable_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1229,7 +1199,6 @@ def test_qMemoryRegionInfo_reports_stack_address_as_readable_writeable_debugserv

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qMemoryRegionInfo_reports_stack_address_as_readable_writeable_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1294,7 +1263,6 @@ def test_qMemoryRegionInfo_reports_heap_address_as_readable_writeable_debugserve

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qMemoryRegionInfo_reports_heap_address_as_readable_writeable_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1411,7 +1379,6 @@ def test_software_breakpoint_set_and_remove_work_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_software_breakpoint_set_and_remove_work_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1442,7 +1409,6 @@ def test_qSupported_returns_known_stub_features_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_qSupported_returns_known_stub_features_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1503,7 +1469,6 @@ def test_written_M_content_reads_back_correctly_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_written_M_content_reads_back_correctly_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1550,7 +1515,6 @@ def test_P_writes_all_gpr_registers_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_P_writes_all_gpr_registers_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down Expand Up @@ -1659,7 +1623,6 @@ def test_P_and_p_thread_suffix_work_debugserver_dsym(self):

@llgs_test
@dwarf_test
@unittest2.expectedFailure()
def test_P_and_p_thread_suffix_work_llgs_dwarf(self):
self.init_llgs_test()
self.buildDwarf()
Expand Down
1 change: 1 addition & 0 deletions lldb/test/tools/lldb-gdbserver/gdbremote_testcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -1024,3 +1024,4 @@ def single_step_only_steps_one_instruction(self, use_Hc_packet=True, step_instru
(state_reached, step_count) = self.count_single_steps_until_true(main_thread_id, self.g_c1_c2_contents_are, args, max_step_count=5, use_Hc_packet=use_Hc_packet, step_instruction=step_instruction)
self.assertTrue(state_reached)
self.assertEquals(step_count, 1)

9 changes: 6 additions & 3 deletions lldb/test/tools/lldb-gdbserver/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,12 @@ signal_handler (int signo)
switch (signo)
{
case SIGSEGV:
// Fix up the pointer we're writing to. This needs to happen if nothing intercepts the SIGSEGV
// (i.e. if somebody runs this from the command line).
longjmp(g_jump_buffer, 1);
if (g_is_segfaulting)
{
// Fix up the pointer we're writing to. This needs to happen if nothing intercepts the SIGSEGV
// (i.e. if somebody runs this from the command line).
longjmp(g_jump_buffer, 1);
}
break;
case SIGUSR1:
if (g_is_segfaulting)
Expand Down
1 change: 1 addition & 0 deletions lldb/tools/debugserver/source/RNBRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2326,6 +2326,7 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
{
size_t thread_name_len = strlen(thread_name);


if (::strcspn (thread_name, "$#+-;:") == thread_name_len)
ostrm << std::hex << "name:" << thread_name << ';';
else
Expand Down
Loading