[Lldb-commits] [PATCH] Merge of Linux and FreeBSD
Johnny Chen
johnny.chen at apple.com
Thu Jan 5 10:57:13 PST 2012
Hi Dawn,
I will commit the POSIX patch for you in a moment.
Thanks.
On Jan 4, 2012, at 7:25 PM, dawn at burble.org wrote:
> The commit failed with:
>
> svn: Commit failed (details follow):
> svn: Server sent unexpected return value (400 Bad Request) in response to MKACTIVITY request for '/svn/llvm-project/!svn/act/171a3442-2c78-47b3-89ac-63b98af59774'
> svn: Your commit message was left in a temporary file:
> svn: '/home/dawn/dev/llvm_svnR146622/tools/lldb/svn-commit.tmp'
>
> I tried checking out the tree with:
> svn co https://llvm.org/svn/llvm-project
> but that gave me:
> svn: access to '/svn/llvm-project/!svn/vcc/default' forbidden
>
> Please commit lldb_svnR147560_POSIX.patch for me?
> Commit message is:
>
> This patch combines common code from Linux and FreeBSD into
> a new POSIX platform. It also contains fixes for 64bit FreeBSD.
>
> The patch is based on changes by Mark Peek <mp at FreeBSD.org> and
> "K. Macy" <kmacy at freebsd.org> in their github repo located at
> https://github.com/fbsd/lldb.
>
> Thanks,
> -Dawn
>
> On Wed, Jan 04, 2012 at 06:04:17PM -0800, dawn at burble.org wrote:
>> Looks like only source/Target/Platform.cpp had left-overs from the
>> bad git patch, so we're good now.
>>
>> New patches attached:
>> lldb_svnR147560_POSIX_TargetList.patch - changes to TargetList.cpp separated out.
>> lldb_svnR147560_POSIX.patch - changes sans Platform.cpp and TargetList.cpp
>>
>> The changes to TargetList.cpp are needed by both BSD and Linux in order for
>> Attach() to work. I spent a lot of time debugging this one, and the BSD folks
>> came to the same conclusion. I'll dig through my notes and try to write up my
>> findings - should this be discussed here or on lldb-dev?
>>
>> So I should go ahead and commit the rest of the patch? I've commited to clang
>> but never lldb - I can give it a try...
>>
>> Thanks,
>> -Dawn
>>
>> On Wed, Jan 04, 2012 at 05:11:13PM -0800, dawn at burble.org wrote:
>>> On Wed, Jan 04, 2012 at 04:41:08PM -0800, Johnny Chen wrote:
>>>> Hi Dawn,
>>>>
>>>> The patch looks good. I have a couple of questions on source/Target/Platform.cpp and source/Target/TargetList.cpp, though.
>>>> Please commit the patch except the two files.
>>>>
>>>> Here are my questions:
>>>>
>>>> The Platform.cpp patch looks wrong?
>>>
>>> Sorry - you're right. That was a left over from a mis-applied git patch
>>> that I thought I had reverted. I will fix ASAP and resubmit.
>>>
>>> Thanks for catching this!!!
>>>
>>> ...stay tuned...
>>>
>>>> Index: source/Target/Platform.cpp
>>>> ===================================================================
>>>> --- source/Target/Platform.cpp (revision 147560)
>>>> +++ source/Target/Platform.cpp (working copy)
>>>> @@ -572,6 +572,16 @@
>>>> Error &error)
>>>> {
>>>> ProcessSP process_sp;
>>>> +
>>>> + 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;
>>>> +
>>>> +
>>>> +#if 0
>>>> + ProcessSP process_sp;
>>>> // Make sure we stop at the entry point
>>>> launch_info.GetFlags ().Set (eLaunchFlagDebug);
>>>> error = LaunchProcess (launch_info);
>>>> @@ -602,4 +612,5 @@
>>>> }
>>>> }
>>>> return process_sp;
>>>> +#endif
>>>> }
>>>>
>>>> Also, I'll ask Greg to review the TargetList.cpp question you have.
>>>> Please don't commit it for the time being.
>>>>
>>>> Index: source/Target/TargetList.cpp
>>>> ===================================================================
>>>> --- source/Target/TargetList.cpp (revision 147560)
>>>> +++ 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,
>>>>
>>>> On Jan 4, 2012, at 3:26 PM, dawn at burble.org wrote:
>>>>
>>>>>
>>>>> This patch combines common code from Linux and FreeBSD into
>>>>> a new POSIX platform. It also contains fixes for 64bit FreeBSD.
>>>>>
>>>>> The patch is based on changes by Mark Peek <mp at FreeBSD.org> and
>>>>> "K. Macy" <kmacy at freebsd.org> in their
>>>>> github repo located at https://github.com/fbsd/lldb.
>>>>>
>>>>> Ok to commit?
>>>>> Thanks!
>>>>> -Dawn
>>>>> <lldb_svnR147560_POSIX.patch>_______________________________________________
>>>>> lldb-commits mailing list
>>>>> lldb-commits at cs.uiuc.edu
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
>>> _______________________________________________
>>> lldb-commits mailing list
>>> lldb-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
>
>> Index: source/Target/TargetList.cpp
>> ===================================================================
>> --- source/Target/TargetList.cpp (revision 147560)
>> +++ 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: include/lldb/Host/Host.h
>> ===================================================================
>> --- include/lldb/Host/Host.h (revision 147560)
>> +++ 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 147560)
>> +++ source/Plugins/Platform/Linux/PlatformLinux.h (working copy)
>> @@ -104,6 +104,7 @@
>> Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
>> Target *target, Listener &listener, Error &error);
>>
>> + // Linux processes can not be launched by spawning and attaching.
>> virtual bool
>> CanDebugProcess ()
>> {
>> Index: source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
>> ===================================================================
>> --- source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp (revision 147560)
>> +++ 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),
>> @@ -79,7 +76,7 @@
>> void
>> PlatformFreeBSD::Terminate ()
>> {
>> - PluginManager::UnregisterPlugin (PlatformFreeBSD::CreateInstance);
>> + PluginManager::UnregisterPlugin (PlatformFreeBSD::CreateInstance);
>> }
>>
>> //------------------------------------------------------------------
>> @@ -385,17 +382,16 @@
>> 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 +434,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 +453,7 @@
>> emptyFileSpec,
>> emptyArchSpec,
>> false,
>> + m_remote_platform_sp,
>> new_target_sp);
>> target = new_target_sp.get();
>> }
>> @@ -472,13 +469,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 147560)
>> +++ source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h (working copy)
>> @@ -132,12 +132,16 @@
>> 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,
>> lldb_private::Error &error);
>>
>> + // FreeBSD processes can not be launched by spawning and attaching.
>> + virtual bool
>> + CanDebugProcess () { return false; }
>> +
>> // Only on PlatformMacOSX:
>> virtual lldb_private::Error
>> GetFile (const lldb_private::FileSpec &platform_file,
>> Index: source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp
>> ===================================================================
>> --- source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp (revision 147560)
>> +++ source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp (working copy)
>> @@ -1,191 +0,0 @@
>> -//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===//
>> -//
>> -// The LLVM Compiler Infrastructure
>> -//
>> -// This file is distributed under the University of Illinois Open Source
>> -// License. See LICENSE.TXT for details.
>> -//
>> -//===----------------------------------------------------------------------===//
>> -
>> -// C Includes
>> -#include <fcntl.h>
>> -#include <sys/stat.h>
>> -#include <sys/types.h>
>> -
>> -// C++ Includes
>> -// Other libraries and framework includes
>> -#include "lldb/Core/DataBufferHeap.h"
>> -#include "lldb/Core/DataExtractor.h"
>> -#include "lldb/Core/Log.h"
>> -#include "lldb/Target/Process.h"
>> -
>> -#include "AuxVector.h"
>> -
>> -using namespace lldb;
>> -using namespace lldb_private;
>> -
>> -static bool
>> -GetMaxU64(DataExtractor &data,
>> - uint32_t *offset, uint64_t *value, unsigned int byte_size)
>> -{
>> - uint32_t saved_offset = *offset;
>> - *value = data.GetMaxU64(offset, byte_size);
>> - return *offset != saved_offset;
>> -}
>> -
>> -static bool
>> -ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry,
>> - uint32_t *offset, unsigned int byte_size)
>> -{
>> - if (!GetMaxU64(data, offset, &entry.type, byte_size))
>> - return false;
>> -
>> - if (!GetMaxU64(data, offset, &entry.value, byte_size))
>> - return false;
>> -
>> - return true;
>> -}
>> -
>> -DataBufferSP
>> -AuxVector::GetAuxvData()
>> -{
>> - static const size_t path_size = 128;
>> - static char path[path_size];
>> - 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", m_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<DataBufferHeap> 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;
>> -}
>> -
>> -void
>> -AuxVector::ParseAuxv(DataExtractor &data)
>> -{
>> - const unsigned int byte_size = m_process->GetAddressByteSize();
>> - uint32_t offset = 0;
>> -
>> - for (;;)
>> - {
>> - Entry entry;
>> -
>> - if (!ParseAuxvEntry(data, entry, &offset, byte_size))
>> - break;
>> -
>> - if (entry.type == AT_NULL)
>> - break;
>> -
>> - if (entry.type == AT_IGNORE)
>> - continue;
>> -
>> - m_auxv.push_back(entry);
>> - }
>> -}
>> -
>> -AuxVector::AuxVector(Process *process)
>> - : m_process(process)
>> -{
>> - DataExtractor data;
>> - LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
>> -
>> - data.SetData(GetAuxvData());
>> - data.SetByteOrder(m_process->GetByteOrder());
>> - data.SetAddressByteSize(m_process->GetAddressByteSize());
>> -
>> - ParseAuxv(data);
>> -
>> - if (log)
>> - DumpToLog(log);
>> -}
>> -
>> -AuxVector::iterator
>> -AuxVector::FindEntry(EntryType type) const
>> -{
>> - for (iterator I = begin(); I != end(); ++I)
>> - {
>> - if (I->type == static_cast<uint64_t>(type))
>> - return I;
>> - }
>> -
>> - return end();
>> -}
>> -
>> -void
>> -AuxVector::DumpToLog(LogSP log) const
>> -{
>> - if (!log)
>> - return;
>> -
>> - log->PutCString("AuxVector: ");
>> - for (iterator I = begin(); I != end(); ++I)
>> - {
>> - log->Printf(" %s [%d]: %lx", GetEntryName(*I), I->type, I->value);
>> - }
>> -}
>> -
>> -const char *
>> -AuxVector::GetEntryName(EntryType type)
>> -{
>> - const char *name;
>> -
>> -#define ENTRY_NAME(_type) _type: name = #_type
>> - switch (type)
>> - {
>> - default:
>> - name = "unkown";
>> - break;
>> -
>> - case ENTRY_NAME(AT_NULL); break;
>> - case ENTRY_NAME(AT_IGNORE); break;
>> - case ENTRY_NAME(AT_EXECFD); break;
>> - case ENTRY_NAME(AT_PHDR); break;
>> - case ENTRY_NAME(AT_PHENT); break;
>> - case ENTRY_NAME(AT_PHNUM); break;
>> - case ENTRY_NAME(AT_PAGESZ); break;
>> - case ENTRY_NAME(AT_BASE); break;
>> - case ENTRY_NAME(AT_FLAGS); break;
>> - case ENTRY_NAME(AT_ENTRY); break;
>> - case ENTRY_NAME(AT_NOTELF); break;
>> - case ENTRY_NAME(AT_UID); break;
>> - case ENTRY_NAME(AT_EUID); break;
>> - case ENTRY_NAME(AT_GID); break;
>> - case ENTRY_NAME(AT_EGID); break;
>> - case ENTRY_NAME(AT_CLKTCK); break;
>> - }
>> -#undef ENTRY_NAME
>> -
>> - return name;
>> -}
>> -
>> Index: source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp
>> ===================================================================
>> --- source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp (revision 147560)
>> +++ source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp (working copy)
>> @@ -1,322 +0,0 @@
>> -//===-- DYLDRendezvous.cpp --------------------------------------*- C++ -*-===//
>> -//
>> -// The LLVM Compiler Infrastructure
>> -//
>> -// This file is distributed under the University of Illinois Open Source
>> -// License. See LICENSE.TXT for details.
>> -//
>> -//===----------------------------------------------------------------------===//
>> -
>> -// C Includes
>> -// C++ Includes
>> -// Other libraries and framework includes
>> -#include "lldb/Core/ArchSpec.h"
>> -#include "lldb/Core/Error.h"
>> -#include "lldb/Core/Log.h"
>> -#include "lldb/Target/Process.h"
>> -#include "lldb/Target/Target.h"
>> -
>> -#include "DYLDRendezvous.h"
>> -
>> -using namespace lldb;
>> -using namespace lldb_private;
>> -
>> -/// Locates the address of the rendezvous structure. Returns the address on
>> -/// success and LLDB_INVALID_ADDRESS on failure.
>> -static addr_t
>> -ResolveRendezvousAddress(Process *process)
>> -{
>> - addr_t info_location;
>> - addr_t info_addr;
>> - Error error;
>> - size_t size;
>> -
>> - info_location = process->GetImageInfoAddress();
>> -
>> - if (info_location == LLDB_INVALID_ADDRESS)
>> - return LLDB_INVALID_ADDRESS;
>> -
>> - info_addr = 0;
>> - size = process->DoReadMemory(info_location, &info_addr,
>> - process->GetAddressByteSize(), error);
>> - if (size != process->GetAddressByteSize() || error.Fail())
>> - return LLDB_INVALID_ADDRESS;
>> -
>> - if (info_addr == 0)
>> - return LLDB_INVALID_ADDRESS;
>> -
>> - return info_addr;
>> -}
>> -
>> -DYLDRendezvous::DYLDRendezvous(Process *process)
>> - : m_process(process),
>> - m_rendezvous_addr(LLDB_INVALID_ADDRESS),
>> - m_current(),
>> - m_previous(),
>> - m_soentries(),
>> - m_added_soentries(),
>> - m_removed_soentries()
>> -{
>> -}
>> -
>> -bool
>> -DYLDRendezvous::Resolve()
>> -{
>> - const size_t word_size = 4;
>> - Rendezvous info;
>> - size_t address_size;
>> - size_t padding;
>> - addr_t info_addr;
>> - addr_t cursor;
>> -
>> - address_size = m_process->GetAddressByteSize();
>> - padding = address_size - word_size;
>> -
>> - if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
>> - cursor = info_addr = ResolveRendezvousAddress(m_process);
>> - else
>> - cursor = info_addr = m_rendezvous_addr;
>> -
>> - if (cursor == LLDB_INVALID_ADDRESS)
>> - return false;
>> -
>> - if (!(cursor = ReadMemory(cursor, &info.version, word_size)))
>> - return false;
>> -
>> - if (!(cursor = ReadMemory(cursor + padding, &info.map_addr, address_size)))
>> - return false;
>> -
>> - if (!(cursor = ReadMemory(cursor, &info.brk, address_size)))
>> - return false;
>> -
>> - if (!(cursor = ReadMemory(cursor, &info.state, word_size)))
>> - return false;
>> -
>> - if (!(cursor = ReadMemory(cursor + padding, &info.ldbase, address_size)))
>> - return false;
>> -
>> - // The rendezvous was successfully read. Update our internal state.
>> - m_rendezvous_addr = info_addr;
>> - m_previous = m_current;
>> - m_current = info;
>> -
>> - return UpdateSOEntries();
>> -}
>> -
>> -bool
>> -DYLDRendezvous::IsValid()
>> -{
>> - return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
>> -}
>> -
>> -bool
>> -DYLDRendezvous::UpdateSOEntries()
>> -{
>> - SOEntry entry;
>> -
>> - if (m_current.map_addr == 0)
>> - return false;
>> -
>> - // When the previous and current states are consistent this is the first
>> - // time we have been asked to update. Just take a snapshot of the currently
>> - // loaded modules.
>> - if (m_previous.state == eConsistent && m_current.state == eConsistent)
>> - return TakeSnapshot(m_soentries);
>> -
>> - // If we are about to add or remove a shared object clear out the current
>> - // state and take a snapshot of the currently loaded images.
>> - if (m_current.state == eAdd || m_current.state == eDelete)
>> - {
>> - assert(m_previous.state == eConsistent);
>> - m_soentries.clear();
>> - m_added_soentries.clear();
>> - m_removed_soentries.clear();
>> - return TakeSnapshot(m_soentries);
>> - }
>> - assert(m_current.state == eConsistent);
>> -
>> - // Otherwise check the previous state to determine what to expect and update
>> - // accordingly.
>> - if (m_previous.state == eAdd)
>> - return UpdateSOEntriesForAddition();
>> - else if (m_previous.state == eDelete)
>> - return UpdateSOEntriesForDeletion();
>> -
>> - return false;
>> -}
>> -
>> -bool
>> -DYLDRendezvous::UpdateSOEntriesForAddition()
>> -{
>> - SOEntry entry;
>> - iterator pos;
>> -
>> - assert(m_previous.state == eAdd);
>> -
>> - if (m_current.map_addr == 0)
>> - return false;
>> -
>> - for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
>> - {
>> - if (!ReadSOEntryFromMemory(cursor, entry))
>> - return false;
>> -
>> - if (entry.path.empty())
>> - continue;
>> -
>> - pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
>> - if (pos == m_soentries.end())
>> - {
>> - m_soentries.push_back(entry);
>> - m_added_soentries.push_back(entry);
>> - }
>> - }
>> -
>> - return true;
>> -}
>> -
>> -bool
>> -DYLDRendezvous::UpdateSOEntriesForDeletion()
>> -{
>> - SOEntryList entry_list;
>> - iterator pos;
>> -
>> - assert(m_previous.state == eDelete);
>> -
>> - if (!TakeSnapshot(entry_list))
>> - return false;
>> -
>> - for (iterator I = begin(); I != end(); ++I)
>> - {
>> - pos = std::find(entry_list.begin(), entry_list.end(), *I);
>> - if (pos == entry_list.end())
>> - m_removed_soentries.push_back(*I);
>> - }
>> -
>> - m_soentries = entry_list;
>> - return true;
>> -}
>> -
>> -bool
>> -DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
>> -{
>> - SOEntry entry;
>> -
>> - if (m_current.map_addr == 0)
>> - return false;
>> -
>> - for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
>> - {
>> - if (!ReadSOEntryFromMemory(cursor, entry))
>> - return false;
>> -
>> - if (entry.path.empty())
>> - continue;
>> -
>> - entry_list.push_back(entry);
>> - }
>> -
>> - return true;
>> -}
>> -
>> -addr_t
>> -DYLDRendezvous::ReadMemory(addr_t addr, void *dst, size_t size)
>> -{
>> - size_t bytes_read;
>> - Error error;
>> -
>> - bytes_read = m_process->DoReadMemory(addr, dst, size, error);
>> - if (bytes_read != size || error.Fail())
>> - return 0;
>> -
>> - return addr + bytes_read;
>> -}
>> -
>> -std::string
>> -DYLDRendezvous::ReadStringFromMemory(addr_t addr)
>> -{
>> - std::string str;
>> - Error error;
>> - size_t size;
>> - char c;
>> -
>> - if (addr == LLDB_INVALID_ADDRESS)
>> - return std::string();
>> -
>> - for (;;) {
>> - size = m_process->DoReadMemory(addr, &c, 1, error);
>> - if (size != 1 || error.Fail())
>> - return std::string();
>> - if (c == 0)
>> - break;
>> - else {
>> - str.push_back(c);
>> - addr++;
>> - }
>> - }
>> -
>> - return str;
>> -}
>> -
>> -bool
>> -DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
>> -{
>> - size_t address_size = m_process->GetAddressByteSize();
>> -
>> - entry.clear();
>> -
>> - if (!(addr = ReadMemory(addr, &entry.base_addr, address_size)))
>> - return false;
>> -
>> - if (!(addr = ReadMemory(addr, &entry.path_addr, address_size)))
>> - return false;
>> -
>> - if (!(addr = ReadMemory(addr, &entry.dyn_addr, address_size)))
>> - return false;
>> -
>> - if (!(addr = ReadMemory(addr, &entry.next, address_size)))
>> - return false;
>> -
>> - if (!(addr = ReadMemory(addr, &entry.prev, address_size)))
>> - return false;
>> -
>> - entry.path = ReadStringFromMemory(entry.path_addr);
>> -
>> - return true;
>> -}
>> -
>> -void
>> -DYLDRendezvous::DumpToLog(LogSP log) const
>> -{
>> - int state = GetState();
>> -
>> - if (!log)
>> - return;
>> -
>> - log->PutCString("DYLDRendezvous:");
>> - log->Printf(" Address: %lx", GetRendezvousAddress());
>> - log->Printf(" Version: %d", GetVersion());
>> - log->Printf(" Link : %lx", GetLinkMapAddress());
>> - log->Printf(" Break : %lx", GetBreakAddress());
>> - log->Printf(" LDBase : %lx", GetLDBase());
>> - log->Printf(" State : %s",
>> - (state == eConsistent) ? "consistent" :
>> - (state == eAdd) ? "add" :
>> - (state == eDelete) ? "delete" : "unknown");
>> -
>> - iterator I = begin();
>> - iterator E = end();
>> -
>> - if (I != E)
>> - log->PutCString("DYLDRendezvous SOEntries:");
>> -
>> - for (int i = 1; I != E; ++I, ++i)
>> - {
>> - log->Printf("\n SOEntry [%d] %s", i, I->path.c_str());
>> - log->Printf(" Base : %lx", I->base_addr);
>> - log->Printf(" Path : %lx", I->path_addr);
>> - log->Printf(" Dyn : %lx", I->dyn_addr);
>> - log->Printf(" Next : %lx", I->next);
>> - log->Printf(" Prev : %lx", I->prev);
>> - }
>> -}
>> Index: source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h
>> ===================================================================
>> --- source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h (revision 147560)
>> +++ source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h (working copy)
>> @@ -1,97 +0,0 @@
>> -//===-- AuxVector.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_AuxVector_H_
>> -#define liblldb_AuxVector_H_
>> -
>> -// C Includes
>> -// C++ Includes
>> -#include <vector>
>> -
>> -// Other libraries and framework includes
>> -#include "lldb/lldb-forward-rtti.h"
>> -
>> -namespace lldb_private {
>> -class DataExtractor;
>> -}
>> -
>> -/// @class AuxVector
>> -/// @brief Represents a processes auxiliary vector.
>> -///
>> -/// When a process is loaded on Linux a vector of values is placed onto the
>> -/// stack communicating operating system specific information. On construction
>> -/// this class locates and parses this information and provides a simple
>> -/// read-only interface to the entries found.
>> -class AuxVector {
>> -
>> -public:
>> - AuxVector(lldb_private::Process *process);
>> -
>> - struct Entry {
>> - uint64_t type;
>> - uint64_t value;
>> -
>> - Entry() : type(0), value(0) { }
>> - };
>> -
>> - /// Constants describing the type of entry.
>> - enum EntryType {
>> - AT_NULL = 0, ///< End of auxv.
>> - AT_IGNORE = 1, ///< Ignore entry.
>> - AT_EXECFD = 2, ///< File descriptor of program.
>> - AT_PHDR = 3, ///< Program headers.
>> - AT_PHENT = 4, ///< Size of program header.
>> - AT_PHNUM = 5, ///< Number of program headers.
>> - AT_PAGESZ = 6, ///< Page size.
>> - AT_BASE = 7, ///< Interpreter base address.
>> - AT_FLAGS = 8, ///< Flags.
>> - AT_ENTRY = 9, ///< Program entry point.
>> - AT_NOTELF = 10, ///< Set if program is not an ELF.
>> - AT_UID = 11, ///< UID.
>> - AT_EUID = 12, ///< Effective UID.
>> - AT_GID = 13, ///< GID.
>> - AT_EGID = 14, ///< Effective GID.
>> - AT_CLKTCK = 17 ///< Clock frequency (e.g. times(2)).
>> - };
>> -
>> -private:
>> - typedef std::vector<Entry> EntryVector;
>> -
>> -public:
>> - typedef EntryVector::const_iterator iterator;
>> -
>> - iterator begin() const { return m_auxv.begin(); }
>> - iterator end() const { return m_auxv.end(); }
>> -
>> - iterator
>> - FindEntry(EntryType type) const;
>> -
>> - static const char *
>> - GetEntryName(const Entry &entry) {
>> - return GetEntryName(static_cast<EntryType>(entry.type));
>> - }
>> -
>> - static const char *
>> - GetEntryName(EntryType type);
>> -
>> - void
>> - DumpToLog(lldb::LogSP log) const;
>> -
>> -private:
>> - lldb_private::Process *m_process;
>> - EntryVector m_auxv;
>> -
>> - lldb::DataBufferSP
>> - GetAuxvData();
>> -
>> - void
>> - ParseAuxv(lldb_private::DataExtractor &data);
>> -};
>> -
>> -#endif
>> Index: source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h
>> ===================================================================
>> --- source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h (revision 147560)
>> +++ source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h (working copy)
>> @@ -1,227 +0,0 @@
>> -//===-- DYLDRendezvous.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_Rendezvous_H_
>> -#define liblldb_Rendezvous_H_
>> -
>> -// C Includes
>> -// C++ Includes
>> -#include <list>
>> -#include <string>
>> -
>> -// Other libraries and framework includes
>> -#include "lldb/lldb-defines.h"
>> -#include "lldb/lldb-types.h"
>> -
>> -namespace lldb_private {
>> -class Process;
>> -}
>> -
>> -/// @class DYLDRendezvous
>> -/// @brief Interface to the runtime linker.
>> -///
>> -/// A structure is present in a processes memory space which is updated by the
>> -/// runtime liker each time a module is loaded or unloaded. This class provides
>> -/// an interface to this structure and maintains a consistent snapshot of the
>> -/// currently loaded modules.
>> -class DYLDRendezvous {
>> -
>> - // This structure is used to hold the contents of the debug rendezvous
>> - // information (struct r_debug) as found in the inferiors memory. Note that
>> - // the layout of this struct is not binary compatible, it is simply large
>> - // enough to hold the information on both 32 and 64 bit platforms.
>> - struct Rendezvous {
>> - uint64_t version;
>> - lldb::addr_t map_addr;
>> - lldb::addr_t brk;
>> - uint64_t state;
>> - lldb::addr_t ldbase;
>> -
>> - Rendezvous()
>> - : version(0), map_addr(0), brk(0), state(0), ldbase(0) { }
>> - };
>> -
>> -public:
>> - DYLDRendezvous(lldb_private::Process *process);
>> -
>> - /// Update the internal snapshot of runtime linker rendezvous and recompute
>> - /// the currently loaded modules.
>> - ///
>> - /// This method should be called once one start up, then once each time the
>> - /// runtime linker enters the function given by GetBreakAddress().
>> - ///
>> - /// @returns true on success and false on failure.
>> - ///
>> - /// @see GetBreakAddress().
>> - bool
>> - Resolve();
>> -
>> - /// @returns true if this rendezvous has been located in the inferiors
>> - /// address space and false otherwise.
>> - bool
>> - IsValid();
>> -
>> - /// @returns the address of the rendezvous structure in the inferiors
>> - /// address space.
>> - lldb::addr_t
>> - GetRendezvousAddress() const { return m_rendezvous_addr; }
>> -
>> - /// @returns the version of the rendezvous protocol being used.
>> - int
>> - GetVersion() const { return m_current.version; }
>> -
>> - /// @returns address in the inferiors address space containing the linked
>> - /// list of shared object descriptors.
>> - lldb::addr_t
>> - GetLinkMapAddress() const { return m_current.map_addr; }
>> -
>> - /// A breakpoint should be set at this address and Resolve called on each
>> - /// hit.
>> - ///
>> - /// @returns the address of a function called by the runtime linker each
>> - /// time a module is loaded/unloaded, or about to be loaded/unloaded.
>> - ///
>> - /// @see Resolve()
>> - lldb::addr_t
>> - GetBreakAddress() const { return m_current.brk; }
>> -
>> - /// Returns the current state of the rendezvous structure.
>> - int
>> - GetState() const { return m_current.state; }
>> -
>> - /// @returns the base address of the runtime linker in the inferiors address
>> - /// space.
>> - lldb::addr_t
>> - GetLDBase() const { return m_current.ldbase; }
>> -
>> - /// @returns true if modules have been loaded into the inferior since the
>> - /// last call to Resolve().
>> - bool
>> - ModulesDidLoad() const { return !m_added_soentries.empty(); }
>> -
>> - /// @returns true if modules have been unloaded from the inferior since the
>> - /// last call to Resolve().
>> - bool
>> - ModulesDidUnload() const { return !m_removed_soentries.empty(); }
>> -
>> - void
>> - DumpToLog(lldb::LogSP log) const;
>> -
>> - /// @brief Constants describing the state of the rendezvous.
>> - ///
>> - /// @see GetState().
>> - enum RendezvousState {
>> - eConsistent,
>> - eAdd,
>> - eDelete
>> - };
>> -
>> - /// @brief Structure representing the shared objects currently loaded into
>> - /// the inferior process.
>> - ///
>> - /// This object is a rough analogue to the struct link_map object which
>> - /// actually lives in the inferiors memory.
>> - struct SOEntry {
>> - lldb::addr_t base_addr; ///< Base address of the loaded object.
>> - lldb::addr_t path_addr; ///< String naming the shared object.
>> - lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
>> - lldb::addr_t next; ///< Address of next so_entry.
>> - lldb::addr_t prev; ///< Address of previous so_entry.
>> - std::string path; ///< File name of shared object.
>> -
>> - SOEntry() { clear(); }
>> -
>> - bool operator ==(const SOEntry &entry) {
>> - return this->path == entry.path;
>> - }
>> -
>> - void clear() {
>> - base_addr = 0;
>> - path_addr = 0;
>> - dyn_addr = 0;
>> - next = 0;
>> - prev = 0;
>> - path.clear();
>> - }
>> - };
>> -
>> -protected:
>> - typedef std::list<SOEntry> SOEntryList;
>> -
>> -public:
>> - typedef SOEntryList::const_iterator iterator;
>> -
>> - /// Iterators over all currently loaded modules.
>> - iterator begin() const { return m_soentries.begin(); }
>> - iterator end() const { return m_soentries.end(); }
>> -
>> - /// Iterators over all modules loaded into the inferior since the last call
>> - /// to Resolve().
>> - iterator loaded_begin() const { return m_added_soentries.begin(); }
>> - iterator loaded_end() const { return m_added_soentries.end(); }
>> -
>> - /// Iterators over all modules unloaded from the inferior since the last
>> - /// call to Resolve().
>> - iterator unloaded_begin() const { return m_removed_soentries.begin(); }
>> - iterator unloaded_end() const { return m_removed_soentries.end(); }
>> -
>> -protected:
>> - lldb_private::Process *m_process;
>> -
>> - /// Location of the r_debug structure in the inferiors address space.
>> - lldb::addr_t m_rendezvous_addr;
>> -
>> - /// Current and previous snapshots of the rendezvous structure.
>> - Rendezvous m_current;
>> - Rendezvous m_previous;
>> -
>> - /// List of SOEntry objects corresponding to the current link map state.
>> - SOEntryList m_soentries;
>> -
>> - /// List of SOEntry's added to the link map since the last call to Resolve().
>> - SOEntryList m_added_soentries;
>> -
>> - /// List of SOEntry's removed from the link map since the last call to
>> - /// Resolve().
>> - SOEntryList m_removed_soentries;
>> -
>> - /// Reads @p size bytes from the inferiors address space starting at @p
>> - /// addr.
>> - ///
>> - /// @returns addr + size if the read was successful and false otherwise.
>> - lldb::addr_t
>> - ReadMemory(lldb::addr_t addr, void *dst, size_t size);
>> -
>> - /// Reads a null-terminated C string from the memory location starting at @p
>> - /// addr.
>> - std::string
>> - ReadStringFromMemory(lldb::addr_t addr);
>> -
>> - /// Reads an SOEntry starting at @p addr.
>> - bool
>> - ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
>> -
>> - /// Updates the current set of SOEntries, the set of added entries, and the
>> - /// set of removed entries.
>> - bool
>> - UpdateSOEntries();
>> -
>> - bool
>> - UpdateSOEntriesForAddition();
>> -
>> - bool
>> - UpdateSOEntriesForDeletion();
>> -
>> - /// Reads the current list of shared objects according to the link map
>> - /// supplied by the runtime linker.
>> - bool
>> - TakeSnapshot(SOEntryList &entry_list);
>> -};
>> -
>> -#endif
>> Index: source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp
>> ===================================================================
>> --- source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp (revision 147560)
>> +++ source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp (working copy)
>> @@ -1,423 +0,0 @@
>> -//===-- DynamicLoaderLinux.h ------------------------------------*- C++ -*-===//
>> -//
>> -// The LLVM Compiler Infrastructure
>> -//
>> -// This file is distributed under the University of Illinois Open Source
>> -// License. See LICENSE.TXT for details.
>> -//
>> -//===----------------------------------------------------------------------===//
>> -
>> -// C Includes
>> -// C++ Includes
>> -// Other libraries and framework includes
>> -#include "lldb/Core/PluginManager.h"
>> -#include "lldb/Core/Log.h"
>> -#include "lldb/Target/Process.h"
>> -#include "lldb/Target/Target.h"
>> -#include "lldb/Target/Thread.h"
>> -#include "lldb/Target/ThreadPlanRunToAddress.h"
>> -
>> -#include "AuxVector.h"
>> -#include "DynamicLoaderLinuxDYLD.h"
>> -
>> -using namespace lldb;
>> -using namespace lldb_private;
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::Initialize()
>> -{
>> - PluginManager::RegisterPlugin(GetPluginNameStatic(),
>> - GetPluginDescriptionStatic(),
>> - CreateInstance);
>> -}
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::Terminate()
>> -{
>> -}
>> -
>> -const char *
>> -DynamicLoaderLinuxDYLD::GetPluginName()
>> -{
>> - return "DynamicLoaderLinuxDYLD";
>> -}
>> -
>> -const char *
>> -DynamicLoaderLinuxDYLD::GetShortPluginName()
>> -{
>> - return "linux-dyld";
>> -}
>> -
>> -const char *
>> -DynamicLoaderLinuxDYLD::GetPluginNameStatic()
>> -{
>> - return "dynamic-loader.linux-dyld";
>> -}
>> -
>> -const char *
>> -DynamicLoaderLinuxDYLD::GetPluginDescriptionStatic()
>> -{
>> - return "Dynamic loader plug-in that watches for shared library "
>> - "loads/unloads in Linux processes.";
>> -}
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::GetPluginCommandHelp(const char *command, Stream *strm)
>> -{
>> -}
>> -
>> -uint32_t
>> -DynamicLoaderLinuxDYLD::GetPluginVersion()
>> -{
>> - return 1;
>> -}
>> -
>> -DynamicLoader *
>> -DynamicLoaderLinuxDYLD::CreateInstance(Process *process, bool force)
>> -{
>> - bool create = force;
>> - if (!create)
>> - {
>> - const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
>> - if (triple_ref.getOS() == llvm::Triple::Linux)
>> - create = true;
>> - }
>> -
>> - if (create)
>> - return new DynamicLoaderLinuxDYLD (process);
>> - return NULL;
>> -}
>> -
>> -DynamicLoaderLinuxDYLD::DynamicLoaderLinuxDYLD(Process *process)
>> - : DynamicLoader(process),
>> - m_rendezvous(process),
>> - m_load_offset(LLDB_INVALID_ADDRESS),
>> - m_entry_point(LLDB_INVALID_ADDRESS),
>> - m_auxv(NULL)
>> -{
>> -}
>> -
>> -DynamicLoaderLinuxDYLD::~DynamicLoaderLinuxDYLD()
>> -{
>> -}
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::DidAttach()
>> -{
>> - ModuleSP executable;
>> - addr_t load_offset;
>> -
>> - m_auxv.reset(new AuxVector(m_process));
>> -
>> - executable = m_process->GetTarget().GetExecutableModule();
>> - load_offset = ComputeLoadOffset();
>> -
>> - if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
>> - {
>> - ModuleList module_list;
>> - module_list.Append(executable);
>> - UpdateLoadedSections(executable, load_offset);
>> - m_process->GetTarget().ModulesDidLoad(module_list);
>> - }
>> -}
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::DidLaunch()
>> -{
>> - ModuleSP executable;
>> - addr_t load_offset;
>> -
>> - m_auxv.reset(new AuxVector(m_process));
>> -
>> - executable = m_process->GetTarget().GetExecutableModule();
>> - load_offset = ComputeLoadOffset();
>> -
>> - if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
>> - {
>> - ModuleList module_list;
>> - module_list.Append(executable);
>> - UpdateLoadedSections(executable, load_offset);
>> - ProbeEntry();
>> - m_process->GetTarget().ModulesDidLoad(module_list);
>> - }
>> -}
>> -
>> -Error
>> -DynamicLoaderLinuxDYLD::ExecutePluginCommand(Args &command, Stream *strm)
>> -{
>> - return Error();
>> -}
>> -
>> -Log *
>> -DynamicLoaderLinuxDYLD::EnablePluginLogging(Stream *strm, Args &command)
>> -{
>> - return NULL;
>> -}
>> -
>> -Error
>> -DynamicLoaderLinuxDYLD::CanLoadImage()
>> -{
>> - return Error();
>> -}
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::UpdateLoadedSections(ModuleSP module, addr_t base_addr)
>> -{
>> - ObjectFile *obj_file = module->GetObjectFile();
>> - SectionList *sections = obj_file->GetSectionList();
>> - SectionLoadList &load_list = m_process->GetTarget().GetSectionLoadList();
>> - const size_t num_sections = sections->GetSize();
>> -
>> - for (unsigned i = 0; i < num_sections; ++i)
>> - {
>> - Section *section = sections->GetSectionAtIndex(i).get();
>> - lldb::addr_t new_load_addr = section->GetFileAddress() + base_addr;
>> - lldb::addr_t old_load_addr = load_list.GetSectionLoadAddress(section);
>> -
>> - // If the file address of the section is zero then this is not an
>> - // allocatable/loadable section (property of ELF sh_addr). Skip it.
>> - if (new_load_addr == base_addr)
>> - continue;
>> -
>> - if (old_load_addr == LLDB_INVALID_ADDRESS ||
>> - old_load_addr != new_load_addr)
>> - load_list.SetSectionLoadAddress(section, new_load_addr);
>> - }
>> -}
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::ProbeEntry()
>> -{
>> - Breakpoint *entry_break;
>> - addr_t entry;
>> -
>> - if ((entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
>> - return;
>> -
>> - entry_break = m_process->GetTarget().CreateBreakpoint(entry, true).get();
>> - entry_break->SetCallback(EntryBreakpointHit, this, true);
>> -}
>> -
>> -// The runtime linker has run and initialized the rendezvous structure once the
>> -// process has hit its entry point. When we hit the corresponding breakpoint we
>> -// interrogate the rendezvous structure to get the load addresses of all
>> -// dependent modules for the process. Similarly, we can discover the runtime
>> -// linker function and setup a breakpoint to notify us of any dynamically loaded
>> -// modules (via dlopen).
>> -bool
>> -DynamicLoaderLinuxDYLD::EntryBreakpointHit(void *baton,
>> - StoppointCallbackContext *context,
>> - user_id_t break_id,
>> - user_id_t break_loc_id)
>> -{
>> - DynamicLoaderLinuxDYLD* dyld_instance;
>> -
>> - dyld_instance = static_cast<DynamicLoaderLinuxDYLD*>(baton);
>> - dyld_instance->LoadAllCurrentModules();
>> - dyld_instance->SetRendezvousBreakpoint();
>> - return false; // Continue running.
>> -}
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::SetRendezvousBreakpoint()
>> -{
>> - Breakpoint *dyld_break;
>> - addr_t break_addr;
>> -
>> - break_addr = m_rendezvous.GetBreakAddress();
>> - dyld_break = m_process->GetTarget().CreateBreakpoint(break_addr, true).get();
>> - dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
>> -}
>> -
>> -bool
>> -DynamicLoaderLinuxDYLD::RendezvousBreakpointHit(void *baton,
>> - StoppointCallbackContext *context,
>> - user_id_t break_id,
>> - user_id_t break_loc_id)
>> -{
>> - DynamicLoaderLinuxDYLD* dyld_instance;
>> -
>> - dyld_instance = static_cast<DynamicLoaderLinuxDYLD*>(baton);
>> - dyld_instance->RefreshModules();
>> -
>> - // Return true to stop the target, false to just let the target run.
>> - return dyld_instance->GetStopWhenImagesChange();
>> -}
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::RefreshModules()
>> -{
>> - if (!m_rendezvous.Resolve())
>> - return;
>> -
>> - DYLDRendezvous::iterator I;
>> - DYLDRendezvous::iterator E;
>> -
>> - ModuleList &loaded_modules = m_process->GetTarget().GetImages();
>> -
>> - if (m_rendezvous.ModulesDidLoad())
>> - {
>> - ModuleList new_modules;
>> -
>> - E = m_rendezvous.loaded_end();
>> - for (I = m_rendezvous.loaded_begin(); I != E; ++I)
>> - {
>> - FileSpec file(I->path.c_str(), true);
>> - ModuleSP module_sp = LoadModuleAtAddress(file, I->base_addr);
>> - if (module_sp.get())
>> - new_modules.Append(module_sp);
>> - }
>> - m_process->GetTarget().ModulesDidLoad(new_modules);
>> - }
>> -
>> - if (m_rendezvous.ModulesDidUnload())
>> - {
>> - ModuleList old_modules;
>> -
>> - E = m_rendezvous.unloaded_end();
>> - for (I = m_rendezvous.unloaded_begin(); I != E; ++I)
>> - {
>> - FileSpec file(I->path.c_str(), true);
>> - ModuleSP module_sp =
>> - loaded_modules.FindFirstModuleForFileSpec(file, NULL, NULL);
>> - if (module_sp.get())
>> - old_modules.Append(module_sp);
>> - }
>> - m_process->GetTarget().ModulesDidUnload(old_modules);
>> - }
>> -}
>> -
>> -ThreadPlanSP
>> -DynamicLoaderLinuxDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
>> -{
>> - LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
>> - ThreadPlanSP thread_plan_sp;
>> -
>> - StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
>> - const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
>> - Symbol *sym = context.symbol;
>> -
>> - if (sym == NULL || !sym->IsTrampoline())
>> - return thread_plan_sp;
>> -
>> - const ConstString &sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled);
>> - if (!sym_name)
>> - return thread_plan_sp;
>> -
>> - SymbolContextList target_symbols;
>> - Target &target = thread.GetProcess().GetTarget();
>> - ModuleList &images = target.GetImages();
>> -
>> - images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
>> - size_t num_targets = target_symbols.GetSize();
>> - if (!num_targets)
>> - return thread_plan_sp;
>> -
>> - typedef std::vector<lldb::addr_t> AddressVector;
>> - AddressVector addrs;
>> - for (size_t i = 0; i < num_targets; ++i)
>> - {
>> - SymbolContext context;
>> - AddressRange range;
>> - if (target_symbols.GetContextAtIndex(i, context))
>> - {
>> - context.GetAddressRange(eSymbolContextEverything, 0, false, range);
>> - lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
>> - if (addr != LLDB_INVALID_ADDRESS)
>> - addrs.push_back(addr);
>> - }
>> - }
>> -
>> - if (addrs.size() > 0)
>> - {
>> - AddressVector::iterator start = addrs.begin();
>> - AddressVector::iterator end = addrs.end();
>> -
>> - std::sort(start, end);
>> - addrs.erase(std::unique(start, end), end);
>> - thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
>> - }
>> -
>> - return thread_plan_sp;
>> -}
>> -
>> -void
>> -DynamicLoaderLinuxDYLD::LoadAllCurrentModules()
>> -{
>> - DYLDRendezvous::iterator I;
>> - DYLDRendezvous::iterator E;
>> - ModuleList module_list;
>> -
>> - if (!m_rendezvous.Resolve())
>> - return;
>> -
>> - for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
>> - {
>> - FileSpec file(I->path.c_str(), false);
>> - ModuleSP module_sp = LoadModuleAtAddress(file, I->base_addr);
>> - if (module_sp.get())
>> - module_list.Append(module_sp);
>> - }
>> -
>> - m_process->GetTarget().ModulesDidLoad(module_list);
>> -}
>> -
>> -ModuleSP
>> -DynamicLoaderLinuxDYLD::LoadModuleAtAddress(const FileSpec &file, addr_t base_addr)
>> -{
>> - Target &target = m_process->GetTarget();
>> - ModuleList &modules = target.GetImages();
>> - ModuleSP module_sp;
>> -
>> - if ((module_sp = modules.FindFirstModuleForFileSpec(file, NULL, NULL)))
>> - {
>> - UpdateLoadedSections(module_sp, base_addr);
>> - }
>> - else if ((module_sp = target.GetSharedModule(file, target.GetArchitecture())))
>> - {
>> - UpdateLoadedSections(module_sp, base_addr);
>> - modules.Append(module_sp);
>> - }
>> -
>> - return module_sp;
>> -}
>> -
>> -addr_t
>> -DynamicLoaderLinuxDYLD::ComputeLoadOffset()
>> -{
>> - addr_t virt_entry;
>> -
>> - if (m_load_offset != LLDB_INVALID_ADDRESS)
>> - return m_load_offset;
>> -
>> - if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
>> - return LLDB_INVALID_ADDRESS;
>> -
>> - ModuleSP module = m_process->GetTarget().GetExecutableModule();
>> - ObjectFile *exe = module->GetObjectFile();
>> - Address file_entry = exe->GetEntryPointAddress();
>> -
>> - if (!file_entry.IsValid())
>> - return LLDB_INVALID_ADDRESS;
>> -
>> - m_load_offset = virt_entry - file_entry.GetFileAddress();
>> - return m_load_offset;
>> -}
>> -
>> -addr_t
>> -DynamicLoaderLinuxDYLD::GetEntryPoint()
>> -{
>> - if (m_entry_point != LLDB_INVALID_ADDRESS)
>> - return m_entry_point;
>> -
>> - if (m_auxv.get() == NULL)
>> - return LLDB_INVALID_ADDRESS;
>> -
>> - AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_ENTRY);
>> -
>> - if (I == m_auxv->end())
>> - return LLDB_INVALID_ADDRESS;
>> -
>> - m_entry_point = static_cast<addr_t>(I->value);
>> - return m_entry_point;
>> -}
>> Index: source/Plugins/DynamicLoader/Linux-DYLD/Makefile
>> ===================================================================
>> --- source/Plugins/DynamicLoader/Linux-DYLD/Makefile (revision 147560)
>> +++ source/Plugins/DynamicLoader/Linux-DYLD/Makefile (working copy)
>> @@ -1,14 +0,0 @@
>> -##===- source/Plugins/DynamicLoader/Linux-DYLD/Makefile ----*- Makefile -*-===##
>> -#
>> -# The LLVM Compiler Infrastructure
>> -#
>> -# This file is distributed under the University of Illinois Open Source
>> -# License. See LICENSE.TXT for details.
>> -#
>> -##===----------------------------------------------------------------------===##
>> -
>> -LLDB_LEVEL := ../../../..
>> -LIBRARYNAME := lldbPluginDynamicLoaderLinux
>> -BUILD_ARCHIVE = 1
>> -
>> -include $(LLDB_LEVEL)/Makefile
>> Index: source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h
>> ===================================================================
>> --- source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h (revision 147560)
>> +++ source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h (working copy)
>> @@ -1,165 +0,0 @@
>> -//===-- DynamicLoaderLinux.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_DynamicLoaderLinux_H_
>> -#define liblldb_DynamicLoaderLinux_H_
>> -
>> -// C Includes
>> -// C++ Includes
>> -// Other libraries and framework includes
>> -#include "lldb/Breakpoint/StoppointCallbackContext.h"
>> -#include "lldb/Target/DynamicLoader.h"
>> -
>> -#include "DYLDRendezvous.h"
>> -
>> -class AuxVector;
>> -
>> -class DynamicLoaderLinuxDYLD : public lldb_private::DynamicLoader
>> -{
>> -public:
>> -
>> - static void
>> - Initialize();
>> -
>> - static void
>> - Terminate();
>> -
>> - static const char *
>> - GetPluginNameStatic();
>> -
>> - static const char *
>> - GetPluginDescriptionStatic();
>> -
>> - static lldb_private::DynamicLoader *
>> - CreateInstance(lldb_private::Process *process, bool force);
>> -
>> - DynamicLoaderLinuxDYLD(lldb_private::Process *process);
>> -
>> - virtual
>> - ~DynamicLoaderLinuxDYLD();
>> -
>> - //------------------------------------------------------------------
>> - // DynamicLoader protocol
>> - //------------------------------------------------------------------
>> -
>> - virtual void
>> - DidAttach();
>> -
>> - virtual void
>> - DidLaunch();
>> -
>> - virtual lldb::ThreadPlanSP
>> - GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
>> - bool stop_others);
>> -
>> - virtual lldb_private::Error
>> - CanLoadImage();
>> -
>> - //------------------------------------------------------------------
>> - // PluginInterface protocol
>> - //------------------------------------------------------------------
>> - virtual const char *
>> - GetPluginName();
>> -
>> - virtual const char *
>> - GetShortPluginName();
>> -
>> - virtual uint32_t
>> - GetPluginVersion();
>> -
>> - virtual void
>> - GetPluginCommandHelp(const char *command, lldb_private::Stream *strm);
>> -
>> - virtual lldb_private::Error
>> - ExecutePluginCommand(lldb_private::Args &command, lldb_private::Stream *strm);
>> -
>> - virtual lldb_private::Log *
>> - EnablePluginLogging(lldb_private::Stream *strm, lldb_private::Args &command);
>> -
>> -protected:
>> - /// Runtime linker rendezvous structure.
>> - DYLDRendezvous m_rendezvous;
>> -
>> - /// Virtual load address of the inferior process.
>> - lldb::addr_t m_load_offset;
>> -
>> - /// Virtual entry address of the inferior process.
>> - lldb::addr_t m_entry_point;
>> -
>> - /// Auxiliary vector of the inferior process.
>> - std::auto_ptr<AuxVector> m_auxv;
>> -
>> - /// Enables a breakpoint on a function called by the runtime
>> - /// linker each time a module is loaded or unloaded.
>> - void
>> - SetRendezvousBreakpoint();
>> -
>> - /// Callback routine which updates the current list of loaded modules based
>> - /// on the information supplied by the runtime linker.
>> - static bool
>> - RendezvousBreakpointHit(void *baton,
>> - lldb_private::StoppointCallbackContext *context,
>> - lldb::user_id_t break_id,
>> - lldb::user_id_t break_loc_id);
>> -
>> - /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
>> - /// of loaded modules.
>> - void
>> - RefreshModules();
>> -
>> - /// Updates the load address of every allocatable section in @p module.
>> - ///
>> - /// @param module The module to traverse.
>> - ///
>> - /// @param base_addr The virtual base address @p module is loaded at.
>> - void
>> - UpdateLoadedSections(lldb::ModuleSP module,
>> - lldb::addr_t base_addr = 0);
>> -
>> - /// Locates or creates a module given by @p file and updates/loads the
>> - /// resulting module at the virtual base address @p base_addr.
>> - lldb::ModuleSP
>> - LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t base_addr);
>> -
>> - /// Resolves the entry point for the current inferior process and sets a
>> - /// breakpoint at that address.
>> - void
>> - ProbeEntry();
>> -
>> - /// Callback routine invoked when we hit the breakpoint on process entry.
>> - ///
>> - /// This routine is responsible for resolving the load addresses of all
>> - /// dependent modules required by the inferior and setting up the rendezvous
>> - /// breakpoint.
>> - static bool
>> - EntryBreakpointHit(void *baton,
>> - lldb_private::StoppointCallbackContext *context,
>> - lldb::user_id_t break_id,
>> - lldb::user_id_t break_loc_id);
>> -
>> - /// Helper for the entry breakpoint callback. Resolves the load addresses
>> - /// of all dependent modules.
>> - void
>> - LoadAllCurrentModules();
>> -
>> - /// Computes a value for m_load_offset returning the computed address on
>> - /// success and LLDB_INVALID_ADDRESS on failure.
>> - lldb::addr_t
>> - ComputeLoadOffset();
>> -
>> - /// Computes a value for m_entry_point returning the computed address on
>> - /// success and LLDB_INVALID_ADDRESS on failure.
>> - lldb::addr_t
>> - GetEntryPoint();
>> -
>> -private:
>> - DISALLOW_COPY_AND_ASSIGN(DynamicLoaderLinuxDYLD);
>> -};
>> -
>> -#endif // liblldb_DynamicLoaderLinuxDYLD_H_
>> Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
>> ===================================================================
>> --- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h (revision 0)
>> +++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h (revision 0)
>> @@ -0,0 +1,165 @@
>> +//===-- DynamicLoaderPOSIX.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_DynamicLoaderPOSIX_H_
>> +#define liblldb_DynamicLoaderPOSIX_H_
>> +
>> +// C Includes
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +#include "lldb/Breakpoint/StoppointCallbackContext.h"
>> +#include "lldb/Target/DynamicLoader.h"
>> +
>> +#include "DYLDRendezvous.h"
>> +
>> +class AuxVector;
>> +
>> +class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader
>> +{
>> +public:
>> +
>> + static void
>> + Initialize();
>> +
>> + static void
>> + Terminate();
>> +
>> + static const char *
>> + GetPluginNameStatic();
>> +
>> + static const char *
>> + GetPluginDescriptionStatic();
>> +
>> + static lldb_private::DynamicLoader *
>> + CreateInstance(lldb_private::Process *process, bool force);
>> +
>> + DynamicLoaderPOSIXDYLD(lldb_private::Process *process);
>> +
>> + virtual
>> + ~DynamicLoaderPOSIXDYLD();
>> +
>> + //------------------------------------------------------------------
>> + // DynamicLoader protocol
>> + //------------------------------------------------------------------
>> +
>> + virtual void
>> + DidAttach();
>> +
>> + virtual void
>> + DidLaunch();
>> +
>> + virtual lldb::ThreadPlanSP
>> + GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
>> + bool stop_others);
>> +
>> + virtual lldb_private::Error
>> + CanLoadImage();
>> +
>> + //------------------------------------------------------------------
>> + // PluginInterface protocol
>> + //------------------------------------------------------------------
>> + virtual const char *
>> + GetPluginName();
>> +
>> + virtual const char *
>> + GetShortPluginName();
>> +
>> + virtual uint32_t
>> + GetPluginVersion();
>> +
>> + virtual void
>> + GetPluginCommandHelp(const char *command, lldb_private::Stream *strm);
>> +
>> + virtual lldb_private::Error
>> + ExecutePluginCommand(lldb_private::Args &command, lldb_private::Stream *strm);
>> +
>> + virtual lldb_private::Log *
>> + EnablePluginLogging(lldb_private::Stream *strm, lldb_private::Args &command);
>> +
>> +protected:
>> + /// Runtime linker rendezvous structure.
>> + DYLDRendezvous m_rendezvous;
>> +
>> + /// Virtual load address of the inferior process.
>> + lldb::addr_t m_load_offset;
>> +
>> + /// Virtual entry address of the inferior process.
>> + lldb::addr_t m_entry_point;
>> +
>> + /// Auxiliary vector of the inferior process.
>> + std::auto_ptr<AuxVector> m_auxv;
>> +
>> + /// Enables a breakpoint on a function called by the runtime
>> + /// linker each time a module is loaded or unloaded.
>> + void
>> + SetRendezvousBreakpoint();
>> +
>> + /// Callback routine which updates the current list of loaded modules based
>> + /// on the information supplied by the runtime linker.
>> + static bool
>> + RendezvousBreakpointHit(void *baton,
>> + lldb_private::StoppointCallbackContext *context,
>> + lldb::user_id_t break_id,
>> + lldb::user_id_t break_loc_id);
>> +
>> + /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
>> + /// of loaded modules.
>> + void
>> + RefreshModules();
>> +
>> + /// Updates the load address of every allocatable section in @p module.
>> + ///
>> + /// @param module The module to traverse.
>> + ///
>> + /// @param base_addr The virtual base address @p module is loaded at.
>> + void
>> + UpdateLoadedSections(lldb::ModuleSP module,
>> + lldb::addr_t base_addr = 0);
>> +
>> + /// Locates or creates a module given by @p file and updates/loads the
>> + /// resulting module at the virtual base address @p base_addr.
>> + lldb::ModuleSP
>> + LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t base_addr);
>> +
>> + /// Resolves the entry point for the current inferior process and sets a
>> + /// breakpoint at that address.
>> + void
>> + ProbeEntry();
>> +
>> + /// Callback routine invoked when we hit the breakpoint on process entry.
>> + ///
>> + /// This routine is responsible for resolving the load addresses of all
>> + /// dependent modules required by the inferior and setting up the rendezvous
>> + /// breakpoint.
>> + static bool
>> + EntryBreakpointHit(void *baton,
>> + lldb_private::StoppointCallbackContext *context,
>> + lldb::user_id_t break_id,
>> + lldb::user_id_t break_loc_id);
>> +
>> + /// Helper for the entry breakpoint callback. Resolves the load addresses
>> + /// of all dependent modules.
>> + void
>> + LoadAllCurrentModules();
>> +
>> + /// Computes a value for m_load_offset returning the computed address on
>> + /// success and LLDB_INVALID_ADDRESS on failure.
>> + lldb::addr_t
>> + ComputeLoadOffset();
>> +
>> + /// Computes a value for m_entry_point returning the computed address on
>> + /// success and LLDB_INVALID_ADDRESS on failure.
>> + lldb::addr_t
>> + GetEntryPoint();
>> +
>> +private:
>> + DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
>> +};
>> +
>> +#endif // liblldb_DynamicLoaderPOSIXDYLD_H_
>> Index: source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
>> ===================================================================
>> --- source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp (revision 0)
>> +++ source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp (revision 0)
>> @@ -0,0 +1,153 @@
>> +//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +// C Includes
>> +#include <fcntl.h>
>> +#include <sys/stat.h>
>> +#include <sys/types.h>
>> +
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +#include "lldb/Core/DataBufferHeap.h"
>> +#include "lldb/Core/DataExtractor.h"
>> +#include "lldb/Core/Log.h"
>> +#include "lldb/Target/Process.h"
>> +
>> +#include "AuxVector.h"
>> +
>> +using namespace lldb;
>> +using namespace lldb_private;
>> +
>> +static bool
>> +GetMaxU64(DataExtractor &data,
>> + uint32_t *offset, uint64_t *value, unsigned int byte_size)
>> +{
>> + uint32_t saved_offset = *offset;
>> + *value = data.GetMaxU64(offset, byte_size);
>> + return *offset != saved_offset;
>> +}
>> +
>> +static bool
>> +ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry,
>> + uint32_t *offset, unsigned int byte_size)
>> +{
>> + if (!GetMaxU64(data, offset, &entry.type, byte_size))
>> + return false;
>> +
>> + if (!GetMaxU64(data, offset, &entry.value, byte_size))
>> + return false;
>> +
>> + return true;
>> +}
>> +
>> +DataBufferSP
>> +AuxVector::GetAuxvData()
>> +{
>> +
>> + return lldb_private::Host::GetAuxvData(m_process);
>> +}
>> +
>> +void
>> +AuxVector::ParseAuxv(DataExtractor &data)
>> +{
>> + const unsigned int byte_size = m_process->GetAddressByteSize();
>> + uint32_t offset = 0;
>> +
>> + for (;;)
>> + {
>> + Entry entry;
>> +
>> + if (!ParseAuxvEntry(data, entry, &offset, byte_size))
>> + break;
>> +
>> + if (entry.type == AT_NULL)
>> + break;
>> +
>> + if (entry.type == AT_IGNORE)
>> + continue;
>> +
>> + m_auxv.push_back(entry);
>> + }
>> +}
>> +
>> +AuxVector::AuxVector(Process *process)
>> + : m_process(process)
>> +{
>> + DataExtractor data;
>> + LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
>> +
>> + data.SetData(GetAuxvData());
>> + data.SetByteOrder(m_process->GetByteOrder());
>> + data.SetAddressByteSize(m_process->GetAddressByteSize());
>> +
>> + ParseAuxv(data);
>> +
>> + if (log)
>> + DumpToLog(log);
>> +}
>> +
>> +AuxVector::iterator
>> +AuxVector::FindEntry(EntryType type) const
>> +{
>> + for (iterator I = begin(); I != end(); ++I)
>> + {
>> + if (I->type == static_cast<uint64_t>(type))
>> + return I;
>> + }
>> +
>> + return end();
>> +}
>> +
>> +void
>> +AuxVector::DumpToLog(LogSP log) const
>> +{
>> + if (!log)
>> + return;
>> +
>> + log->PutCString("AuxVector: ");
>> + for (iterator I = begin(); I != end(); ++I)
>> + {
>> + log->Printf(" %s [%d]: %lx", GetEntryName(*I), I->type, I->value);
>> + }
>> +}
>> +
>> +const char *
>> +AuxVector::GetEntryName(EntryType type)
>> +{
>> + const char *name;
>> +
>> +#define ENTRY_NAME(_type) _type: name = #_type
>> + switch (type)
>> + {
>> + default:
>> + name = "unkown";
>> + break;
>> +
>> + case ENTRY_NAME(AT_NULL); break;
>> + case ENTRY_NAME(AT_IGNORE); break;
>> + case ENTRY_NAME(AT_EXECFD); break;
>> + case ENTRY_NAME(AT_PHDR); break;
>> + case ENTRY_NAME(AT_PHENT); break;
>> + case ENTRY_NAME(AT_PHNUM); break;
>> + case ENTRY_NAME(AT_PAGESZ); break;
>> + case ENTRY_NAME(AT_BASE); break;
>> + case ENTRY_NAME(AT_FLAGS); break;
>> + case ENTRY_NAME(AT_ENTRY); break;
>> + case ENTRY_NAME(AT_NOTELF); break;
>> + case ENTRY_NAME(AT_UID); break;
>> + case ENTRY_NAME(AT_EUID); break;
>> + case ENTRY_NAME(AT_GID); break;
>> + case ENTRY_NAME(AT_EGID); break;
>> + case ENTRY_NAME(AT_CLKTCK); break;
>> + }
>> +#undef ENTRY_NAME
>> +
>> + return name;
>> +}
>> +
>> Index: source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
>> ===================================================================
>> --- source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp (revision 0)
>> +++ source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp (revision 0)
>> @@ -0,0 +1,330 @@
>> +//===-- DYLDRendezvous.cpp --------------------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +// C Includes
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +#include "lldb/Core/ArchSpec.h"
>> +#include "lldb/Core/Error.h"
>> +#include "lldb/Core/Log.h"
>> +#include "lldb/Target/Process.h"
>> +#include "lldb/Target/Target.h"
>> +
>> +#include "DYLDRendezvous.h"
>> +
>> +using namespace lldb;
>> +using namespace lldb_private;
>> +
>> +/// Locates the address of the rendezvous structure. Returns the address on
>> +/// success and LLDB_INVALID_ADDRESS on failure.
>> +static addr_t
>> +ResolveRendezvousAddress(Process *process)
>> +{
>> + addr_t info_location;
>> + addr_t info_addr;
>> + Error error;
>> + size_t size;
>> +
>> + info_location = process->GetImageInfoAddress();
>> +
>> + if (info_location == LLDB_INVALID_ADDRESS)
>> + return LLDB_INVALID_ADDRESS;
>> +
>> + info_addr = 0;
>> + size = process->DoReadMemory(info_location, &info_addr,
>> + process->GetAddressByteSize(), error);
>> + if (size != process->GetAddressByteSize() || error.Fail())
>> + return LLDB_INVALID_ADDRESS;
>> +
>> + if (info_addr == 0)
>> + return LLDB_INVALID_ADDRESS;
>> +
>> + return info_addr;
>> +}
>> +
>> +DYLDRendezvous::DYLDRendezvous(Process *process)
>> + : m_process(process),
>> + m_rendezvous_addr(LLDB_INVALID_ADDRESS),
>> + m_current(),
>> + m_previous(),
>> + m_soentries(),
>> + m_added_soentries(),
>> + m_removed_soentries()
>> +{
>> + // Cache a copy of the executable path
>> + m_process->GetTarget().GetExecutableModule().get()->GetFileSpec().GetPath(m_exe_path, PATH_MAX);
>> +}
>> +
>> +bool
>> +DYLDRendezvous::Resolve()
>> +{
>> + const size_t word_size = 4;
>> + Rendezvous info;
>> + size_t address_size;
>> + size_t padding;
>> + addr_t info_addr;
>> + addr_t cursor;
>> +
>> + address_size = m_process->GetAddressByteSize();
>> + padding = address_size - word_size;
>> +
>> + if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
>> + cursor = info_addr = ResolveRendezvousAddress(m_process);
>> + else
>> + cursor = info_addr = m_rendezvous_addr;
>> +
>> + if (cursor == LLDB_INVALID_ADDRESS)
>> + return false;
>> +
>> + if (!(cursor = ReadMemory(cursor, &info.version, word_size)))
>> + return false;
>> +
>> + if (!(cursor = ReadMemory(cursor + padding, &info.map_addr, address_size)))
>> + return false;
>> +
>> + if (!(cursor = ReadMemory(cursor, &info.brk, address_size)))
>> + return false;
>> +
>> + if (!(cursor = ReadMemory(cursor, &info.state, word_size)))
>> + return false;
>> +
>> + if (!(cursor = ReadMemory(cursor + padding, &info.ldbase, address_size)))
>> + return false;
>> +
>> + // The rendezvous was successfully read. Update our internal state.
>> + m_rendezvous_addr = info_addr;
>> + m_previous = m_current;
>> + m_current = info;
>> +
>> + return UpdateSOEntries();
>> +}
>> +
>> +bool
>> +DYLDRendezvous::IsValid()
>> +{
>> + return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
>> +}
>> +
>> +bool
>> +DYLDRendezvous::UpdateSOEntries()
>> +{
>> + SOEntry entry;
>> +
>> + if (m_current.map_addr == 0)
>> + return false;
>> +
>> + // When the previous and current states are consistent this is the first
>> + // time we have been asked to update. Just take a snapshot of the currently
>> + // loaded modules.
>> + if (m_previous.state == eConsistent && m_current.state == eConsistent)
>> + return TakeSnapshot(m_soentries);
>> +
>> + // If we are about to add or remove a shared object clear out the current
>> + // state and take a snapshot of the currently loaded images.
>> + if (m_current.state == eAdd || m_current.state == eDelete)
>> + {
>> + assert(m_previous.state == eConsistent);
>> + m_soentries.clear();
>> + m_added_soentries.clear();
>> + m_removed_soentries.clear();
>> + return TakeSnapshot(m_soentries);
>> + }
>> + assert(m_current.state == eConsistent);
>> +
>> + // Otherwise check the previous state to determine what to expect and update
>> + // accordingly.
>> + if (m_previous.state == eAdd)
>> + return UpdateSOEntriesForAddition();
>> + else if (m_previous.state == eDelete)
>> + return UpdateSOEntriesForDeletion();
>> +
>> + return false;
>> +}
>> +
>> +bool
>> +DYLDRendezvous::UpdateSOEntriesForAddition()
>> +{
>> + SOEntry entry;
>> + iterator pos;
>> +
>> + assert(m_previous.state == eAdd);
>> +
>> + if (m_current.map_addr == 0)
>> + return false;
>> +
>> + for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
>> + {
>> + if (!ReadSOEntryFromMemory(cursor, entry))
>> + return false;
>> +
>> + // Only add shared libraries and not the executable.
>> + // On Linux this is indicated by an empty path in the entry.
>> + // On FreeBSD it is the name of the executable.
>> + if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
>> + continue;
>> +
>> + pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
>> + if (pos == m_soentries.end())
>> + {
>> + m_soentries.push_back(entry);
>> + m_added_soentries.push_back(entry);
>> + }
>> + }
>> +
>> + return true;
>> +}
>> +
>> +bool
>> +DYLDRendezvous::UpdateSOEntriesForDeletion()
>> +{
>> + SOEntryList entry_list;
>> + iterator pos;
>> +
>> + assert(m_previous.state == eDelete);
>> +
>> + if (!TakeSnapshot(entry_list))
>> + return false;
>> +
>> + for (iterator I = begin(); I != end(); ++I)
>> + {
>> + pos = std::find(entry_list.begin(), entry_list.end(), *I);
>> + if (pos == entry_list.end())
>> + m_removed_soentries.push_back(*I);
>> + }
>> +
>> + m_soentries = entry_list;
>> + return true;
>> +}
>> +
>> +bool
>> +DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
>> +{
>> + SOEntry entry;
>> +
>> + if (m_current.map_addr == 0)
>> + return false;
>> +
>> + for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
>> + {
>> + if (!ReadSOEntryFromMemory(cursor, entry))
>> + return false;
>> +
>> + // Only add shared libraries and not the executable.
>> + // On Linux this is indicated by an empty path in the entry.
>> + // On FreeBSD it is the name of the executable.
>> + if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
>> + continue;
>> +
>> + entry_list.push_back(entry);
>> + }
>> +
>> + return true;
>> +}
>> +
>> +addr_t
>> +DYLDRendezvous::ReadMemory(addr_t addr, void *dst, size_t size)
>> +{
>> + size_t bytes_read;
>> + Error error;
>> +
>> + bytes_read = m_process->DoReadMemory(addr, dst, size, error);
>> + if (bytes_read != size || error.Fail())
>> + return 0;
>> +
>> + return addr + bytes_read;
>> +}
>> +
>> +std::string
>> +DYLDRendezvous::ReadStringFromMemory(addr_t addr)
>> +{
>> + std::string str;
>> + Error error;
>> + size_t size;
>> + char c;
>> +
>> + if (addr == LLDB_INVALID_ADDRESS)
>> + return std::string();
>> +
>> + for (;;) {
>> + size = m_process->DoReadMemory(addr, &c, 1, error);
>> + if (size != 1 || error.Fail())
>> + return std::string();
>> + if (c == 0)
>> + break;
>> + else {
>> + str.push_back(c);
>> + addr++;
>> + }
>> + }
>> +
>> + return str;
>> +}
>> +
>> +bool
>> +DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
>> +{
>> + size_t address_size = m_process->GetAddressByteSize();
>> +
>> + entry.clear();
>> +
>> + if (!(addr = ReadMemory(addr, &entry.base_addr, address_size)))
>> + return false;
>> +
>> + if (!(addr = ReadMemory(addr, &entry.path_addr, address_size)))
>> + return false;
>> +
>> + if (!(addr = ReadMemory(addr, &entry.dyn_addr, address_size)))
>> + return false;
>> +
>> + if (!(addr = ReadMemory(addr, &entry.next, address_size)))
>> + return false;
>> +
>> + if (!(addr = ReadMemory(addr, &entry.prev, address_size)))
>> + return false;
>> +
>> + entry.path = ReadStringFromMemory(entry.path_addr);
>> +
>> + return true;
>> +}
>> +
>> +void
>> +DYLDRendezvous::DumpToLog(LogSP log) const
>> +{
>> + int state = GetState();
>> +
>> + if (!log)
>> + return;
>> +
>> + log->PutCString("DYLDRendezvous:");
>> + log->Printf(" Address: %lx", GetRendezvousAddress());
>> + log->Printf(" Version: %d", GetVersion());
>> + log->Printf(" Link : %lx", GetLinkMapAddress());
>> + log->Printf(" Break : %lx", GetBreakAddress());
>> + log->Printf(" LDBase : %lx", GetLDBase());
>> + log->Printf(" State : %s",
>> + (state == eConsistent) ? "consistent" :
>> + (state == eAdd) ? "add" :
>> + (state == eDelete) ? "delete" : "unknown");
>> +
>> + iterator I = begin();
>> + iterator E = end();
>> +
>> + if (I != E)
>> + log->PutCString("DYLDRendezvous SOEntries:");
>> +
>> + for (int i = 1; I != E; ++I, ++i)
>> + {
>> + log->Printf("\n SOEntry [%d] %s", i, I->path.c_str());
>> + log->Printf(" Base : %lx", I->base_addr);
>> + log->Printf(" Path : %lx", I->path_addr);
>> + log->Printf(" Dyn : %lx", I->dyn_addr);
>> + log->Printf(" Next : %lx", I->next);
>> + log->Printf(" Prev : %lx", I->prev);
>> + }
>> +}
>> Index: source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
>> ===================================================================
>> --- source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h (revision 0)
>> +++ source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h (revision 0)
>> @@ -0,0 +1,97 @@
>> +//===-- AuxVector.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_AuxVector_H_
>> +#define liblldb_AuxVector_H_
>> +
>> +// C Includes
>> +// C++ Includes
>> +#include <vector>
>> +
>> +// Other libraries and framework includes
>> +#include "lldb/lldb-forward-rtti.h"
>> +
>> +namespace lldb_private {
>> +class DataExtractor;
>> +}
>> +
>> +/// @class AuxVector
>> +/// @brief Represents a processes auxiliary vector.
>> +///
>> +/// When a process is loaded on Linux a vector of values is placed onto the
>> +/// stack communicating operating system specific information. On construction
>> +/// this class locates and parses this information and provides a simple
>> +/// read-only interface to the entries found.
>> +class AuxVector {
>> +
>> +public:
>> + AuxVector(lldb_private::Process *process);
>> +
>> + struct Entry {
>> + uint64_t type;
>> + uint64_t value;
>> +
>> + Entry() : type(0), value(0) { }
>> + };
>> +
>> + /// Constants describing the type of entry.
>> + enum EntryType {
>> + AT_NULL = 0, ///< End of auxv.
>> + AT_IGNORE = 1, ///< Ignore entry.
>> + AT_EXECFD = 2, ///< File descriptor of program.
>> + AT_PHDR = 3, ///< Program headers.
>> + AT_PHENT = 4, ///< Size of program header.
>> + AT_PHNUM = 5, ///< Number of program headers.
>> + AT_PAGESZ = 6, ///< Page size.
>> + AT_BASE = 7, ///< Interpreter base address.
>> + AT_FLAGS = 8, ///< Flags.
>> + AT_ENTRY = 9, ///< Program entry point.
>> + AT_NOTELF = 10, ///< Set if program is not an ELF.
>> + AT_UID = 11, ///< UID.
>> + AT_EUID = 12, ///< Effective UID.
>> + AT_GID = 13, ///< GID.
>> + AT_EGID = 14, ///< Effective GID.
>> + AT_CLKTCK = 17 ///< Clock frequency (e.g. times(2)).
>> + };
>> +
>> +private:
>> + typedef std::vector<Entry> EntryVector;
>> +
>> +public:
>> + typedef EntryVector::const_iterator iterator;
>> +
>> + iterator begin() const { return m_auxv.begin(); }
>> + iterator end() const { return m_auxv.end(); }
>> +
>> + iterator
>> + FindEntry(EntryType type) const;
>> +
>> + static const char *
>> + GetEntryName(const Entry &entry) {
>> + return GetEntryName(static_cast<EntryType>(entry.type));
>> + }
>> +
>> + static const char *
>> + GetEntryName(EntryType type);
>> +
>> + void
>> + DumpToLog(lldb::LogSP log) const;
>> +
>> +private:
>> + lldb_private::Process *m_process;
>> + EntryVector m_auxv;
>> +
>> + lldb::DataBufferSP
>> + GetAuxvData();
>> +
>> + void
>> + ParseAuxv(lldb_private::DataExtractor &data);
>> +};
>> +
>> +#endif
>> Index: source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
>> ===================================================================
>> --- source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h (revision 0)
>> +++ source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h (revision 0)
>> @@ -0,0 +1,230 @@
>> +//===-- DYLDRendezvous.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_Rendezvous_H_
>> +#define liblldb_Rendezvous_H_
>> +
>> +// C Includes
>> +// C++ Includes
>> +#include <list>
>> +#include <string>
>> +
>> +// Other libraries and framework includes
>> +#include "lldb/lldb-defines.h"
>> +#include "lldb/lldb-types.h"
>> +
>> +namespace lldb_private {
>> +class Process;
>> +}
>> +
>> +/// @class DYLDRendezvous
>> +/// @brief Interface to the runtime linker.
>> +///
>> +/// A structure is present in a processes memory space which is updated by the
>> +/// runtime liker each time a module is loaded or unloaded. This class provides
>> +/// an interface to this structure and maintains a consistent snapshot of the
>> +/// currently loaded modules.
>> +class DYLDRendezvous {
>> +
>> + // This structure is used to hold the contents of the debug rendezvous
>> + // information (struct r_debug) as found in the inferiors memory. Note that
>> + // the layout of this struct is not binary compatible, it is simply large
>> + // enough to hold the information on both 32 and 64 bit platforms.
>> + struct Rendezvous {
>> + uint64_t version;
>> + lldb::addr_t map_addr;
>> + lldb::addr_t brk;
>> + uint64_t state;
>> + lldb::addr_t ldbase;
>> +
>> + Rendezvous()
>> + : version(0), map_addr(0), brk(0), state(0), ldbase(0) { }
>> + };
>> +
>> +public:
>> + DYLDRendezvous(lldb_private::Process *process);
>> +
>> + /// Update the internal snapshot of runtime linker rendezvous and recompute
>> + /// the currently loaded modules.
>> + ///
>> + /// This method should be called once one start up, then once each time the
>> + /// runtime linker enters the function given by GetBreakAddress().
>> + ///
>> + /// @returns true on success and false on failure.
>> + ///
>> + /// @see GetBreakAddress().
>> + bool
>> + Resolve();
>> +
>> + /// @returns true if this rendezvous has been located in the inferiors
>> + /// address space and false otherwise.
>> + bool
>> + IsValid();
>> +
>> + /// @returns the address of the rendezvous structure in the inferiors
>> + /// address space.
>> + lldb::addr_t
>> + GetRendezvousAddress() const { return m_rendezvous_addr; }
>> +
>> + /// @returns the version of the rendezvous protocol being used.
>> + int
>> + GetVersion() const { return m_current.version; }
>> +
>> + /// @returns address in the inferiors address space containing the linked
>> + /// list of shared object descriptors.
>> + lldb::addr_t
>> + GetLinkMapAddress() const { return m_current.map_addr; }
>> +
>> + /// A breakpoint should be set at this address and Resolve called on each
>> + /// hit.
>> + ///
>> + /// @returns the address of a function called by the runtime linker each
>> + /// time a module is loaded/unloaded, or about to be loaded/unloaded.
>> + ///
>> + /// @see Resolve()
>> + lldb::addr_t
>> + GetBreakAddress() const { return m_current.brk; }
>> +
>> + /// Returns the current state of the rendezvous structure.
>> + int
>> + GetState() const { return m_current.state; }
>> +
>> + /// @returns the base address of the runtime linker in the inferiors address
>> + /// space.
>> + lldb::addr_t
>> + GetLDBase() const { return m_current.ldbase; }
>> +
>> + /// @returns true if modules have been loaded into the inferior since the
>> + /// last call to Resolve().
>> + bool
>> + ModulesDidLoad() const { return !m_added_soentries.empty(); }
>> +
>> + /// @returns true if modules have been unloaded from the inferior since the
>> + /// last call to Resolve().
>> + bool
>> + ModulesDidUnload() const { return !m_removed_soentries.empty(); }
>> +
>> + void
>> + DumpToLog(lldb::LogSP log) const;
>> +
>> + /// @brief Constants describing the state of the rendezvous.
>> + ///
>> + /// @see GetState().
>> + enum RendezvousState {
>> + eConsistent,
>> + eAdd,
>> + eDelete
>> + };
>> +
>> + /// @brief Structure representing the shared objects currently loaded into
>> + /// the inferior process.
>> + ///
>> + /// This object is a rough analogue to the struct link_map object which
>> + /// actually lives in the inferiors memory.
>> + struct SOEntry {
>> + lldb::addr_t base_addr; ///< Base address of the loaded object.
>> + lldb::addr_t path_addr; ///< String naming the shared object.
>> + lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
>> + lldb::addr_t next; ///< Address of next so_entry.
>> + lldb::addr_t prev; ///< Address of previous so_entry.
>> + std::string path; ///< File name of shared object.
>> +
>> + SOEntry() { clear(); }
>> +
>> + bool operator ==(const SOEntry &entry) {
>> + return this->path == entry.path;
>> + }
>> +
>> + void clear() {
>> + base_addr = 0;
>> + path_addr = 0;
>> + dyn_addr = 0;
>> + next = 0;
>> + prev = 0;
>> + path.clear();
>> + }
>> + };
>> +
>> +protected:
>> + typedef std::list<SOEntry> SOEntryList;
>> +
>> +public:
>> + typedef SOEntryList::const_iterator iterator;
>> +
>> + /// Iterators over all currently loaded modules.
>> + iterator begin() const { return m_soentries.begin(); }
>> + iterator end() const { return m_soentries.end(); }
>> +
>> + /// Iterators over all modules loaded into the inferior since the last call
>> + /// to Resolve().
>> + iterator loaded_begin() const { return m_added_soentries.begin(); }
>> + iterator loaded_end() const { return m_added_soentries.end(); }
>> +
>> + /// Iterators over all modules unloaded from the inferior since the last
>> + /// call to Resolve().
>> + iterator unloaded_begin() const { return m_removed_soentries.begin(); }
>> + iterator unloaded_end() const { return m_removed_soentries.end(); }
>> +
>> +protected:
>> + lldb_private::Process *m_process;
>> +
>> + // Cached copy of executable pathname
>> + char m_exe_path[PATH_MAX];
>> +
>> + /// Location of the r_debug structure in the inferiors address space.
>> + lldb::addr_t m_rendezvous_addr;
>> +
>> + /// Current and previous snapshots of the rendezvous structure.
>> + Rendezvous m_current;
>> + Rendezvous m_previous;
>> +
>> + /// List of SOEntry objects corresponding to the current link map state.
>> + SOEntryList m_soentries;
>> +
>> + /// List of SOEntry's added to the link map since the last call to Resolve().
>> + SOEntryList m_added_soentries;
>> +
>> + /// List of SOEntry's removed from the link map since the last call to
>> + /// Resolve().
>> + SOEntryList m_removed_soentries;
>> +
>> + /// Reads @p size bytes from the inferiors address space starting at @p
>> + /// addr.
>> + ///
>> + /// @returns addr + size if the read was successful and false otherwise.
>> + lldb::addr_t
>> + ReadMemory(lldb::addr_t addr, void *dst, size_t size);
>> +
>> + /// Reads a null-terminated C string from the memory location starting at @p
>> + /// addr.
>> + std::string
>> + ReadStringFromMemory(lldb::addr_t addr);
>> +
>> + /// Reads an SOEntry starting at @p addr.
>> + bool
>> + ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
>> +
>> + /// Updates the current set of SOEntries, the set of added entries, and the
>> + /// set of removed entries.
>> + bool
>> + UpdateSOEntries();
>> +
>> + bool
>> + UpdateSOEntriesForAddition();
>> +
>> + bool
>> + UpdateSOEntriesForDeletion();
>> +
>> + /// Reads the current list of shared objects according to the link map
>> + /// supplied by the runtime linker.
>> + bool
>> + TakeSnapshot(SOEntryList &entry_list);
>> +};
>> +
>> +#endif
>> Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
>> ===================================================================
>> --- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (revision 0)
>> +++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (revision 0)
>> @@ -0,0 +1,425 @@
>> +//===-- DynamicLoaderPOSIX.h ------------------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +// C Includes
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +#include "lldb/Core/PluginManager.h"
>> +#include "lldb/Core/Log.h"
>> +#include "lldb/Target/Process.h"
>> +#include "lldb/Target/Target.h"
>> +#include "lldb/Target/Thread.h"
>> +#include "lldb/Target/ThreadPlanRunToAddress.h"
>> +
>> +#include "AuxVector.h"
>> +#include "DynamicLoaderPOSIXDYLD.h"
>> +
>> +using namespace lldb;
>> +using namespace lldb_private;
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::Initialize()
>> +{
>> + PluginManager::RegisterPlugin(GetPluginNameStatic(),
>> + GetPluginDescriptionStatic(),
>> + CreateInstance);
>> +}
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::Terminate()
>> +{
>> +}
>> +
>> +const char *
>> +DynamicLoaderPOSIXDYLD::GetPluginName()
>> +{
>> + return "DynamicLoaderPOSIXDYLD";
>> +}
>> +
>> +const char *
>> +DynamicLoaderPOSIXDYLD::GetShortPluginName()
>> +{
>> + return "linux-dyld";
>> +}
>> +
>> +const char *
>> +DynamicLoaderPOSIXDYLD::GetPluginNameStatic()
>> +{
>> + return "dynamic-loader.linux-dyld";
>> +}
>> +
>> +const char *
>> +DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic()
>> +{
>> + return "Dynamic loader plug-in that watches for shared library "
>> + "loads/unloads in POSIX processes.";
>> +}
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::GetPluginCommandHelp(const char *command, Stream *strm)
>> +{
>> +}
>> +
>> +uint32_t
>> +DynamicLoaderPOSIXDYLD::GetPluginVersion()
>> +{
>> + return 1;
>> +}
>> +
>> +DynamicLoader *
>> +DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, bool force)
>> +{
>> + bool create = force;
>> + if (!create)
>> + {
>> + const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
>> + if (triple_ref.getOS() == llvm::Triple::Linux ||
>> + triple_ref.getOS() == llvm::Triple::FreeBSD)
>> + create = true;
>> + }
>> +
>> + if (create)
>> + return new DynamicLoaderPOSIXDYLD (process);
>> + return NULL;
>> +}
>> +
>> +DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process)
>> + : DynamicLoader(process),
>> + m_rendezvous(process),
>> + m_load_offset(LLDB_INVALID_ADDRESS),
>> + m_entry_point(LLDB_INVALID_ADDRESS),
>> + m_auxv(NULL)
>> +{
>> +}
>> +
>> +DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD()
>> +{
>> +}
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::DidAttach()
>> +{
>> + ModuleSP executable;
>> + addr_t load_offset;
>> +
>> + m_auxv.reset(new AuxVector(m_process));
>> +
>> + executable = m_process->GetTarget().GetExecutableModule();
>> + load_offset = ComputeLoadOffset();
>> +
>> + if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
>> + {
>> + ModuleList module_list;
>> + module_list.Append(executable);
>> + UpdateLoadedSections(executable, load_offset);
>> + LoadAllCurrentModules();
>> + m_process->GetTarget().ModulesDidLoad(module_list);
>> + }
>> +}
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::DidLaunch()
>> +{
>> + ModuleSP executable;
>> + addr_t load_offset;
>> +
>> + m_auxv.reset(new AuxVector(m_process));
>> +
>> + executable = m_process->GetTarget().GetExecutableModule();
>> + load_offset = ComputeLoadOffset();
>> +
>> + if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
>> + {
>> + ModuleList module_list;
>> + module_list.Append(executable);
>> + UpdateLoadedSections(executable, load_offset);
>> + ProbeEntry();
>> + m_process->GetTarget().ModulesDidLoad(module_list);
>> + }
>> +}
>> +
>> +Error
>> +DynamicLoaderPOSIXDYLD::ExecutePluginCommand(Args &command, Stream *strm)
>> +{
>> + return Error();
>> +}
>> +
>> +Log *
>> +DynamicLoaderPOSIXDYLD::EnablePluginLogging(Stream *strm, Args &command)
>> +{
>> + return NULL;
>> +}
>> +
>> +Error
>> +DynamicLoaderPOSIXDYLD::CanLoadImage()
>> +{
>> + return Error();
>> +}
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, addr_t base_addr)
>> +{
>> + ObjectFile *obj_file = module->GetObjectFile();
>> + SectionList *sections = obj_file->GetSectionList();
>> + SectionLoadList &load_list = m_process->GetTarget().GetSectionLoadList();
>> + const size_t num_sections = sections->GetSize();
>> +
>> + for (unsigned i = 0; i < num_sections; ++i)
>> + {
>> + Section *section = sections->GetSectionAtIndex(i).get();
>> + lldb::addr_t new_load_addr = section->GetFileAddress() + base_addr;
>> + lldb::addr_t old_load_addr = load_list.GetSectionLoadAddress(section);
>> +
>> + // If the file address of the section is zero then this is not an
>> + // allocatable/loadable section (property of ELF sh_addr). Skip it.
>> + if (new_load_addr == base_addr)
>> + continue;
>> +
>> + if (old_load_addr == LLDB_INVALID_ADDRESS ||
>> + old_load_addr != new_load_addr)
>> + load_list.SetSectionLoadAddress(section, new_load_addr);
>> + }
>> +}
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::ProbeEntry()
>> +{
>> + Breakpoint *entry_break;
>> + addr_t entry;
>> +
>> + if ((entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
>> + return;
>> +
>> + entry_break = m_process->GetTarget().CreateBreakpoint(entry, true).get();
>> + entry_break->SetCallback(EntryBreakpointHit, this, true);
>> +}
>> +
>> +// The runtime linker has run and initialized the rendezvous structure once the
>> +// process has hit its entry point. When we hit the corresponding breakpoint we
>> +// interrogate the rendezvous structure to get the load addresses of all
>> +// dependent modules for the process. Similarly, we can discover the runtime
>> +// linker function and setup a breakpoint to notify us of any dynamically loaded
>> +// modules (via dlopen).
>> +bool
>> +DynamicLoaderPOSIXDYLD::EntryBreakpointHit(void *baton,
>> + StoppointCallbackContext *context,
>> + user_id_t break_id,
>> + user_id_t break_loc_id)
>> +{
>> + DynamicLoaderPOSIXDYLD* dyld_instance;
>> +
>> + dyld_instance = static_cast<DynamicLoaderPOSIXDYLD*>(baton);
>> + dyld_instance->LoadAllCurrentModules();
>> + dyld_instance->SetRendezvousBreakpoint();
>> + return false; // Continue running.
>> +}
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint()
>> +{
>> + Breakpoint *dyld_break;
>> + addr_t break_addr;
>> +
>> + break_addr = m_rendezvous.GetBreakAddress();
>> + dyld_break = m_process->GetTarget().CreateBreakpoint(break_addr, true).get();
>> + dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
>> +}
>> +
>> +bool
>> +DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(void *baton,
>> + StoppointCallbackContext *context,
>> + user_id_t break_id,
>> + user_id_t break_loc_id)
>> +{
>> + DynamicLoaderPOSIXDYLD* dyld_instance;
>> +
>> + dyld_instance = static_cast<DynamicLoaderPOSIXDYLD*>(baton);
>> + dyld_instance->RefreshModules();
>> +
>> + // Return true to stop the target, false to just let the target run.
>> + return dyld_instance->GetStopWhenImagesChange();
>> +}
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::RefreshModules()
>> +{
>> + if (!m_rendezvous.Resolve())
>> + return;
>> +
>> + DYLDRendezvous::iterator I;
>> + DYLDRendezvous::iterator E;
>> +
>> + ModuleList &loaded_modules = m_process->GetTarget().GetImages();
>> +
>> + if (m_rendezvous.ModulesDidLoad())
>> + {
>> + ModuleList new_modules;
>> +
>> + E = m_rendezvous.loaded_end();
>> + for (I = m_rendezvous.loaded_begin(); I != E; ++I)
>> + {
>> + FileSpec file(I->path.c_str(), true);
>> + ModuleSP module_sp = LoadModuleAtAddress(file, I->base_addr);
>> + if (module_sp.get())
>> + new_modules.Append(module_sp);
>> + }
>> + m_process->GetTarget().ModulesDidLoad(new_modules);
>> + }
>> +
>> + if (m_rendezvous.ModulesDidUnload())
>> + {
>> + ModuleList old_modules;
>> +
>> + E = m_rendezvous.unloaded_end();
>> + for (I = m_rendezvous.unloaded_begin(); I != E; ++I)
>> + {
>> + FileSpec file(I->path.c_str(), true);
>> + ModuleSP module_sp =
>> + loaded_modules.FindFirstModuleForFileSpec(file, NULL, NULL);
>> + if (module_sp.get())
>> + old_modules.Append(module_sp);
>> + }
>> + m_process->GetTarget().ModulesDidUnload(old_modules);
>> + }
>> +}
>> +
>> +ThreadPlanSP
>> +DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
>> +{
>> + LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
>> + ThreadPlanSP thread_plan_sp;
>> +
>> + StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
>> + const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
>> + Symbol *sym = context.symbol;
>> +
>> + if (sym == NULL || !sym->IsTrampoline())
>> + return thread_plan_sp;
>> +
>> + const ConstString &sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled);
>> + if (!sym_name)
>> + return thread_plan_sp;
>> +
>> + SymbolContextList target_symbols;
>> + Target &target = thread.GetProcess().GetTarget();
>> + ModuleList &images = target.GetImages();
>> +
>> + images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
>> + size_t num_targets = target_symbols.GetSize();
>> + if (!num_targets)
>> + return thread_plan_sp;
>> +
>> + typedef std::vector<lldb::addr_t> AddressVector;
>> + AddressVector addrs;
>> + for (size_t i = 0; i < num_targets; ++i)
>> + {
>> + SymbolContext context;
>> + AddressRange range;
>> + if (target_symbols.GetContextAtIndex(i, context))
>> + {
>> + context.GetAddressRange(eSymbolContextEverything, 0, false, range);
>> + lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
>> + if (addr != LLDB_INVALID_ADDRESS)
>> + addrs.push_back(addr);
>> + }
>> + }
>> +
>> + if (addrs.size() > 0)
>> + {
>> + AddressVector::iterator start = addrs.begin();
>> + AddressVector::iterator end = addrs.end();
>> +
>> + std::sort(start, end);
>> + addrs.erase(std::unique(start, end), end);
>> + thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
>> + }
>> +
>> + return thread_plan_sp;
>> +}
>> +
>> +void
>> +DynamicLoaderPOSIXDYLD::LoadAllCurrentModules()
>> +{
>> + DYLDRendezvous::iterator I;
>> + DYLDRendezvous::iterator E;
>> + ModuleList module_list;
>> +
>> + if (!m_rendezvous.Resolve())
>> + return;
>> +
>> + for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
>> + {
>> + FileSpec file(I->path.c_str(), false);
>> + ModuleSP module_sp = LoadModuleAtAddress(file, I->base_addr);
>> + if (module_sp.get())
>> + module_list.Append(module_sp);
>> + }
>> +
>> + m_process->GetTarget().ModulesDidLoad(module_list);
>> +}
>> +
>> +ModuleSP
>> +DynamicLoaderPOSIXDYLD::LoadModuleAtAddress(const FileSpec &file, addr_t base_addr)
>> +{
>> + Target &target = m_process->GetTarget();
>> + ModuleList &modules = target.GetImages();
>> + ModuleSP module_sp;
>> +
>> + if ((module_sp = modules.FindFirstModuleForFileSpec(file, NULL, NULL)))
>> + {
>> + UpdateLoadedSections(module_sp, base_addr);
>> + }
>> + else if ((module_sp = target.GetSharedModule(file, target.GetArchitecture())))
>> + {
>> + UpdateLoadedSections(module_sp, base_addr);
>> + modules.Append(module_sp);
>> + }
>> +
>> + return module_sp;
>> +}
>> +
>> +addr_t
>> +DynamicLoaderPOSIXDYLD::ComputeLoadOffset()
>> +{
>> + addr_t virt_entry;
>> +
>> + if (m_load_offset != LLDB_INVALID_ADDRESS)
>> + return m_load_offset;
>> +
>> + if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
>> + return LLDB_INVALID_ADDRESS;
>> +
>> + ModuleSP module = m_process->GetTarget().GetExecutableModule();
>> + ObjectFile *exe = module->GetObjectFile();
>> + Address file_entry = exe->GetEntryPointAddress();
>> +
>> + if (!file_entry.IsValid())
>> + return LLDB_INVALID_ADDRESS;
>> +
>> + m_load_offset = virt_entry - file_entry.GetFileAddress();
>> + return m_load_offset;
>> +}
>> +
>> +addr_t
>> +DynamicLoaderPOSIXDYLD::GetEntryPoint()
>> +{
>> + if (m_entry_point != LLDB_INVALID_ADDRESS)
>> + return m_entry_point;
>> +
>> + if (m_auxv.get() == NULL)
>> + return LLDB_INVALID_ADDRESS;
>> +
>> + AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_ENTRY);
>> +
>> + if (I == m_auxv->end())
>> + return LLDB_INVALID_ADDRESS;
>> +
>> + m_entry_point = static_cast<addr_t>(I->value);
>> + return m_entry_point;
>> +}
>> Index: source/Plugins/DynamicLoader/POSIX-DYLD/Makefile
>> ===================================================================
>> --- source/Plugins/DynamicLoader/POSIX-DYLD/Makefile (revision 0)
>> +++ source/Plugins/DynamicLoader/POSIX-DYLD/Makefile (revision 0)
>> @@ -0,0 +1,14 @@
>> +##===- source/Plugins/DynamicLoader/POSIX-DYLD/Makefile ----*- Makefile -*-===##
>> +#
>> +# The LLVM Compiler Infrastructure
>> +#
>> +# This file is distributed under the University of Illinois Open Source
>> +# License. See LICENSE.TXT for details.
>> +#
>> +##===----------------------------------------------------------------------===##
>> +
>> +LLDB_LEVEL := ../../../..
>> +LIBRARYNAME := lldbPluginDynamicLoaderPOSIX
>> +BUILD_ARCHIVE = 1
>> +
>> +include $(LLDB_LEVEL)/Makefile
>> Index: source/Plugins/Makefile
>> ===================================================================
>> --- source/Plugins/Makefile (revision 147560)
>> +++ 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 147560)
>> +++ 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<LinuxThread*>(
>> - 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<LinuxThread*>(
>> - 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
>> ===================================================================
>> --- source/Plugins/Process/Linux/ProcessLinuxLog.cpp (revision 147560)
>> +++ source/Plugins/Process/Linux/ProcessLinuxLog.cpp (working copy)
>> @@ -1,193 +0,0 @@
>> -//===-- ProcessLinuxLog.cpp ---------------------------------------*- C++ -*-===//
>> -//
>> -// The LLVM Compiler Infrastructure
>> -//
>> -// This file is distributed under the University of Illinois Open Source
>> -// License. See LICENSE.TXT for details.
>> -//
>> -//===----------------------------------------------------------------------===//
>> -
>> -#include "ProcessLinuxLog.h"
>> -
>> -#include "lldb/Interpreter/Args.h"
>> -#include "lldb/Core/StreamFile.h"
>> -
>> -#include "ProcessLinux.h"
>> -
>> -using namespace lldb;
>> -using namespace lldb_private;
>> -
>> -
>> -// We want to avoid global constructors where code needs to be run so here we
>> -// control access to our static g_log_sp by hiding it in a singleton function
>> -// that will construct the static g_lob_sp the first time this function is
>> -// called.
>> -static LogSP &
>> -GetLog ()
>> -{
>> - static LogSP g_log_sp;
>> - return g_log_sp;
>> -}
>> -
>> -LogSP
>> -ProcessLinuxLog::GetLogIfAllCategoriesSet (uint32_t mask)
>> -{
>> - LogSP log(GetLog ());
>> - if (log && mask)
>> - {
>> - uint32_t log_mask = log->GetMask().Get();
>> - if ((log_mask & mask) != mask)
>> - return LogSP();
>> - }
>> - return log;
>> -}
>> -
>> -void
>> -ProcessLinuxLog::DisableLog (Args &args, Stream *feedback_strm)
>> -{
>> - LogSP log (GetLog ());
>> - if (log)
>> - {
>> - uint32_t flag_bits = 0;
>> -
>> - const size_t argc = args.GetArgumentCount ();
>> - if (argc > 0)
>> - {
>> - flag_bits = log->GetMask().Get();
>> - for (size_t i = 0; i < argc; ++i)
>> - {
>> - const char *arg = args.GetArgumentAtIndex (i);
>> -
>> -
>> - if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~LINUX_LOG_ALL;
>> - else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~LINUX_LOG_ASYNC;
>> - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~LINUX_LOG_BREAKPOINTS;
>> - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~LINUX_LOG_COMM;
>> - else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~LINUX_LOG_DEFAULT;
>> - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~LINUX_LOG_PACKETS;
>> - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~LINUX_LOG_MEMORY;
>> - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~LINUX_LOG_MEMORY_DATA_SHORT;
>> - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~LINUX_LOG_MEMORY_DATA_LONG;
>> - else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~LINUX_LOG_PROCESS;
>> - else if (::strcasecmp (arg, "ptrace") == 0 ) flag_bits &= ~LINUX_LOG_PTRACE;
>> - else if (::strcasecmp (arg, "registers") == 0 ) flag_bits &= ~LINUX_LOG_REGISTERS;
>> - else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~LINUX_LOG_STEP;
>> - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~LINUX_LOG_THREAD;
>> - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~LINUX_LOG_VERBOSE;
>> - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~LINUX_LOG_WATCHPOINTS;
>> - else
>> - {
>> - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
>> - ListLogCategories (feedback_strm);
>> - }
>> -
>> - }
>> - }
>> -
>> - if (flag_bits == 0)
>> - GetLog ().reset();
>> - else
>> - log->GetMask().Reset (flag_bits);
>> - }
>> -
>> - return;
>> -}
>> -
>> -LogSP
>> -ProcessLinuxLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm)
>> -{
>> - // Try see if there already is a log - that way we can reuse its settings.
>> - // We could reuse the log in toto, but we don't know that the stream is the same.
>> - uint32_t flag_bits = 0;
>> - LogSP log(GetLog ());
>> - if (log)
>> - flag_bits = log->GetMask().Get();
>> -
>> - // Now make a new log with this stream if one was provided
>> - if (log_stream_sp)
>> - {
>> - log = make_shared<Log>(log_stream_sp);
>> - GetLog () = log;
>> - }
>> -
>> - if (log)
>> - {
>> - bool got_unknown_category = false;
>> - const size_t argc = args.GetArgumentCount();
>> - for (size_t i=0; i<argc; ++i)
>> - {
>> - const char *arg = args.GetArgumentAtIndex(i);
>> -
>> - if (::strcasecmp (arg, "all") == 0 ) flag_bits |= LINUX_LOG_ALL;
>> - else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= LINUX_LOG_ASYNC;
>> - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= LINUX_LOG_BREAKPOINTS;
>> - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= LINUX_LOG_COMM;
>> - else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= LINUX_LOG_DEFAULT;
>> - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= LINUX_LOG_PACKETS;
>> - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= LINUX_LOG_MEMORY;
>> - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= LINUX_LOG_MEMORY_DATA_SHORT;
>> - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= LINUX_LOG_MEMORY_DATA_LONG;
>> - else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= LINUX_LOG_PROCESS;
>> - else if (::strcasecmp (arg, "ptrace") == 0 ) flag_bits |= LINUX_LOG_PTRACE;
>> - else if (::strcasecmp (arg, "registers") == 0 ) flag_bits |= LINUX_LOG_REGISTERS;
>> - else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= LINUX_LOG_STEP;
>> - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= LINUX_LOG_THREAD;
>> - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= LINUX_LOG_VERBOSE;
>> - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= LINUX_LOG_WATCHPOINTS;
>> - else
>> - {
>> - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
>> - if (got_unknown_category == false)
>> - {
>> - got_unknown_category = true;
>> - ListLogCategories (feedback_strm);
>> - }
>> - }
>> - }
>> - if (flag_bits == 0)
>> - flag_bits = LINUX_LOG_DEFAULT;
>> - log->GetMask().Reset(flag_bits);
>> - log->GetOptions().Reset(log_options);
>> - }
>> - return log;
>> -}
>> -
>> -void
>> -ProcessLinuxLog::ListLogCategories (Stream *strm)
>> -{
>> - strm->Printf ("Logging categories for '%s':\n"
>> - " all - turn on all available logging categories\n"
>> - " async - log asynchronous activity\n"
>> - " break - log breakpoints\n"
>> - " communication - log communication activity\n"
>> - " default - enable the default set of logging categories for liblldb\n"
>> - " packets - log gdb remote packets\n"
>> - " memory - log memory reads and writes\n"
>> - " data-short - log memory bytes for memory reads and writes for short transactions only\n"
>> - " data-long - log memory bytes for memory reads and writes for all transactions\n"
>> - " process - log process events and activities\n"
>> -#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
>> - " ptrace - log all calls to ptrace\n"
>> -#endif
>> - " registers - log register read/writes\n"
>> - " thread - log thread events and activities\n"
>> - " step - log step related activities\n"
>> - " verbose - enable verbose logging\n"
>> - " watch - log watchpoint related activities\n", ProcessLinux::GetPluginNameStatic());
>> -}
>> -
>> -
>> -void
>> -ProcessLinuxLog::LogIf (uint32_t mask, const char *format, ...)
>> -{
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (mask));
>> - if (log)
>> - {
>> - va_list args;
>> - va_start (args, format);
>> - log->VAPrintf (format, args);
>> - va_end (args);
>> - }
>> -}
>> -
>> -int ProcessLinuxLog::m_nestinglevel;
>> Index: source/Plugins/Process/Linux/ProcessLinux.h
>> ===================================================================
>> --- source/Plugins/Process/Linux/ProcessLinux.h (revision 147560)
>> +++ 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<ProcessMessage> 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<lldb::addr_t, lldb::addr_t> MMapMap;
>> - MMapMap m_addr_to_mmap_size;
>> };
>>
>> #endif // liblldb_MacOSXProcess_H_
>> Index: source/Plugins/Process/Linux/ProcessLinuxLog.h
>> ===================================================================
>> --- source/Plugins/Process/Linux/ProcessLinuxLog.h (revision 147560)
>> +++ source/Plugins/Process/Linux/ProcessLinuxLog.h (working copy)
>> @@ -1,98 +0,0 @@
>> -//===-- ProcessLinuxLog.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_ProcessLinuxLog_h_
>> -#define liblldb_ProcessLinuxLog_h_
>> -
>> -// C Includes
>> -// C++ Includes
>> -// Other libraries and framework includes
>> -
>> -// Project includes
>> -#include "lldb/Core/Log.h"
>> -
>> -#define LINUX_LOG_VERBOSE (1u << 0)
>> -#define LINUX_LOG_PROCESS (1u << 1)
>> -#define LINUX_LOG_THREAD (1u << 2)
>> -#define LINUX_LOG_PACKETS (1u << 3)
>> -#define LINUX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
>> -#define LINUX_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes
>> -#define LINUX_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
>> -#define LINUX_LOG_BREAKPOINTS (1u << 7)
>> -#define LINUX_LOG_WATCHPOINTS (1u << 8)
>> -#define LINUX_LOG_STEP (1u << 9)
>> -#define LINUX_LOG_COMM (1u << 10)
>> -#define LINUX_LOG_ASYNC (1u << 11)
>> -#define LINUX_LOG_PTRACE (1u << 12)
>> -#define LINUX_LOG_REGISTERS (1u << 13)
>> -#define LINUX_LOG_ALL (UINT32_MAX)
>> -#define LINUX_LOG_DEFAULT LINUX_LOG_PACKETS
>> -
>> -// The size which determines "short memory reads/writes".
>> -#define LINUX_LOG_MEMORY_SHORT_BYTES (4 * sizeof(ptrdiff_t))
>> -
>> -class ProcessLinuxLog
>> -{
>> - static int m_nestinglevel;
>> -
>> -public:
>> - static lldb::LogSP
>> - GetLogIfAllCategoriesSet(uint32_t mask = 0);
>> -
>> - static void
>> - DisableLog (lldb_private::Args &args, lldb_private::Stream *feedback_strm);
>> -
>> - static lldb::LogSP
>> - EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options,
>> - lldb_private::Args &args, lldb_private::Stream *feedback_strm);
>> -
>> - static void
>> - ListLogCategories (lldb_private::Stream *strm);
>> -
>> - static void
>> - LogIf (uint32_t mask, const char *format, ...);
>> -
>> - // The following functions can be used to enable the client to limit
>> - // logging to only the top level function calls. This is useful for
>> - // recursive functions. FIXME: not thread safe!
>> - // Example:
>> - // void NestingFunc() {
>> - // LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet(LINUX_LOG_ALL));
>> - // if (log)
>> - // {
>> - // ProcessLinuxLog::IncNestLevel();
>> - // if (ProcessLinuxLog::AtTopNestLevel())
>> - // log->Print(msg);
>> - // }
>> - // NestingFunc();
>> - // if (log)
>> - // ProcessLinuxLog::DecNestLevel();
>> - // }
>> -
>> - static bool
>> - AtTopNestLevel()
>> - {
>> - return m_nestinglevel == 1;
>> - }
>> -
>> - static void
>> - IncNestLevel()
>> - {
>> - ++m_nestinglevel;
>> - }
>> -
>> - static void
>> - DecNestLevel()
>> - {
>> - --m_nestinglevel;
>> - assert(m_nestinglevel >= 0);
>> - }
>> -};
>> -
>> -#endif // liblldb_ProcessLinuxLog_h_
>> Index: source/Plugins/Process/Linux/RegisterContextLinux.h
>> ===================================================================
>> --- source/Plugins/Process/Linux/RegisterContextLinux.h (revision 147560)
>> +++ source/Plugins/Process/Linux/RegisterContextLinux.h (working copy)
>> @@ -1,40 +0,0 @@
>> -//===-- RegisterContext_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 liblldb_RegisterContextLinux_H_
>> -#define liblldb_RegisterContextLinux_H_
>> -
>> -// C Includes
>> -// C++ Includes
>> -// Other libraries and framework includes
>> -#include "lldb/Target/RegisterContext.h"
>> -
>> -//------------------------------------------------------------------------------
>> -/// @class RegisterContextLinux
>> -///
>> -/// @brief Extends RegisterClass with a few virtual operations useful on Linux.
>> -class RegisterContextLinux
>> - : public lldb_private::RegisterContext
>> -{
>> -public:
>> - RegisterContextLinux(lldb_private::Thread &thread,
>> - uint32_t concrete_frame_idx)
>> - : RegisterContext(thread, concrete_frame_idx) { }
>> -
>> - /// Updates the register state of the associated thread after hitting a
>> - /// breakpoint (if that make sense for the architecture). Default
>> - /// implementation simply returns true for architectures which do not
>> - /// require any update.
>> - ///
>> - /// @return
>> - /// True if the operation succeeded and false otherwise.
>> - virtual bool UpdateAfterBreakpoint() { return true; }
>> -};
>> -
>> -#endif // #ifndef liblldb_RegisterContextLinux_H_
>> Index: source/Plugins/Process/Linux/LinuxStopInfo.cpp
>> ===================================================================
>> --- source/Plugins/Process/Linux/LinuxStopInfo.cpp (revision 147560)
>> +++ source/Plugins/Process/Linux/LinuxStopInfo.cpp (working copy)
>> @@ -1,60 +0,0 @@
>> -//===-- LinuxStopInfo.cpp ---------------------------------------*- C++ -*-===//
>> -//
>> -// The LLVM Compiler Infrastructure
>> -//
>> -// This file is distributed under the University of Illinois Open Source
>> -// License. See LICENSE.TXT for details.
>> -//
>> -//===----------------------------------------------------------------------===//
>> -
>> -#include "LinuxStopInfo.h"
>> -
>> -using namespace lldb;
>> -using namespace lldb_private;
>> -
>> -
>> -//===----------------------------------------------------------------------===//
>> -// LinuxLimboStopInfo
>> -
>> -LinuxLimboStopInfo::~LinuxLimboStopInfo() { }
>> -
>> -lldb::StopReason
>> -LinuxLimboStopInfo::GetStopReason() const
>> -{
>> - return lldb::eStopReasonTrace;
>> -}
>> -
>> -const char *
>> -LinuxLimboStopInfo::GetDescription()
>> -{
>> - return "thread exiting";
>> -}
>> -
>> -bool
>> -LinuxLimboStopInfo::ShouldStop(Event *event_ptr)
>> -{
>> - return true;
>> -}
>> -
>> -bool
>> -LinuxLimboStopInfo::ShouldNotify(Event *event_ptr)
>> -{
>> - return true;
>> -}
>> -
>> -//===----------------------------------------------------------------------===//
>> -// LinuxCrashStopInfo
>> -
>> -LinuxCrashStopInfo::~LinuxCrashStopInfo() { }
>> -
>> -lldb::StopReason
>> -LinuxCrashStopInfo::GetStopReason() const
>> -{
>> - return lldb::eStopReasonException;
>> -}
>> -
>> -const char *
>> -LinuxCrashStopInfo::GetDescription()
>> -{
>> - return ProcessMessage::GetCrashReasonString(m_crash_reason);
>> -}
>> Index: source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp
>> ===================================================================
>> --- source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp (revision 147560)
>> +++ source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp (working copy)
>> @@ -1,650 +0,0 @@
>> -//===-- RegisterContextLinux_i386.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/Core/DataExtractor.h"
>> -#include "lldb/Target/Thread.h"
>> -#include "lldb/Host/Endian.h"
>> -
>> -#include "ProcessLinux.h"
>> -#include "ProcessLinuxLog.h"
>> -#include "ProcessMonitor.h"
>> -#include "RegisterContextLinux_i386.h"
>> -
>> -using namespace lldb_private;
>> -using namespace lldb;
>> -
>> -enum
>> -{
>> - k_first_gpr,
>> - gpr_eax = k_first_gpr,
>> - gpr_ebx,
>> - gpr_ecx,
>> - gpr_edx,
>> - gpr_edi,
>> - gpr_esi,
>> - gpr_ebp,
>> - gpr_esp,
>> - gpr_ss,
>> - gpr_eflags,
>> - gpr_eip,
>> - gpr_cs,
>> - gpr_ds,
>> - gpr_es,
>> - gpr_fs,
>> - gpr_gs,
>> - k_last_gpr = gpr_gs,
>> -
>> - k_first_fpr,
>> - fpu_fcw = k_first_fpr,
>> - fpu_fsw,
>> - fpu_ftw,
>> - fpu_fop,
>> - fpu_ip,
>> - fpu_cs,
>> - fpu_foo,
>> - fpu_fos,
>> - fpu_mxcsr,
>> - fpu_stmm0,
>> - fpu_stmm1,
>> - fpu_stmm2,
>> - fpu_stmm3,
>> - fpu_stmm4,
>> - fpu_stmm5,
>> - fpu_stmm6,
>> - fpu_stmm7,
>> - fpu_xmm0,
>> - fpu_xmm1,
>> - fpu_xmm2,
>> - fpu_xmm3,
>> - fpu_xmm4,
>> - fpu_xmm5,
>> - fpu_xmm6,
>> - fpu_xmm7,
>> - k_last_fpr = fpu_xmm7,
>> -
>> - k_num_registers,
>> - k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
>> - k_num_fpu_registers = k_last_fpr - k_first_fpr + 1
>> -};
>> -
>> -// Number of register sets provided by this context.
>> -enum
>> -{
>> - k_num_register_sets = 2
>> -};
>> -
>> -enum
>> -{
>> - gcc_eax = 0,
>> - gcc_ecx,
>> - gcc_edx,
>> - gcc_ebx,
>> - gcc_ebp,
>> - gcc_esp,
>> - gcc_esi,
>> - gcc_edi,
>> - gcc_eip,
>> - gcc_eflags
>> -};
>> -
>> -enum
>> -{
>> - dwarf_eax = 0,
>> - dwarf_ecx,
>> - dwarf_edx,
>> - dwarf_ebx,
>> - dwarf_esp,
>> - dwarf_ebp,
>> - dwarf_esi,
>> - dwarf_edi,
>> - dwarf_eip,
>> - dwarf_eflags,
>> - dwarf_stmm0 = 11,
>> - dwarf_stmm1,
>> - dwarf_stmm2,
>> - dwarf_stmm3,
>> - dwarf_stmm4,
>> - dwarf_stmm5,
>> - dwarf_stmm6,
>> - dwarf_stmm7,
>> - dwarf_xmm0 = 21,
>> - dwarf_xmm1,
>> - dwarf_xmm2,
>> - dwarf_xmm3,
>> - dwarf_xmm4,
>> - dwarf_xmm5,
>> - dwarf_xmm6,
>> - dwarf_xmm7
>> -};
>> -
>> -enum
>> -{
>> - gdb_eax = 0,
>> - gdb_ecx = 1,
>> - gdb_edx = 2,
>> - gdb_ebx = 3,
>> - gdb_esp = 4,
>> - gdb_ebp = 5,
>> - gdb_esi = 6,
>> - gdb_edi = 7,
>> - gdb_eip = 8,
>> - gdb_eflags = 9,
>> - gdb_cs = 10,
>> - gdb_ss = 11,
>> - gdb_ds = 12,
>> - gdb_es = 13,
>> - gdb_fs = 14,
>> - gdb_gs = 15,
>> - gdb_stmm0 = 16,
>> - gdb_stmm1 = 17,
>> - gdb_stmm2 = 18,
>> - gdb_stmm3 = 19,
>> - gdb_stmm4 = 20,
>> - gdb_stmm5 = 21,
>> - gdb_stmm6 = 22,
>> - gdb_stmm7 = 23,
>> - gdb_fcw = 24,
>> - gdb_fsw = 25,
>> - gdb_ftw = 26,
>> - gdb_fpu_cs = 27,
>> - gdb_ip = 28,
>> - gdb_fpu_ds = 29,
>> - gdb_dp = 30,
>> - gdb_fop = 31,
>> - gdb_xmm0 = 32,
>> - gdb_xmm1 = 33,
>> - gdb_xmm2 = 34,
>> - gdb_xmm3 = 35,
>> - gdb_xmm4 = 36,
>> - gdb_xmm5 = 37,
>> - gdb_xmm6 = 38,
>> - gdb_xmm7 = 39,
>> - gdb_mxcsr = 40,
>> - gdb_mm0 = 41,
>> - gdb_mm1 = 42,
>> - gdb_mm2 = 43,
>> - gdb_mm3 = 44,
>> - gdb_mm4 = 45,
>> - gdb_mm5 = 46,
>> - gdb_mm6 = 47,
>> - gdb_mm7 = 48
>> -};
>> -
>> -static const
>> -uint32_t g_gpr_regnums[k_num_gpr_registers] =
>> -{
>> - gpr_eax,
>> - gpr_ebx,
>> - gpr_ecx,
>> - gpr_edx,
>> - gpr_edi,
>> - gpr_esi,
>> - gpr_ebp,
>> - gpr_esp,
>> - gpr_ss,
>> - gpr_eflags,
>> - gpr_eip,
>> - gpr_cs,
>> - gpr_ds,
>> - gpr_es,
>> - gpr_fs,
>> - gpr_gs,
>> -};
>> -
>> -static const uint32_t
>> -g_fpu_regnums[k_num_fpu_registers] =
>> -{
>> - fpu_fcw,
>> - fpu_fsw,
>> - fpu_ftw,
>> - fpu_fop,
>> - fpu_ip,
>> - fpu_cs,
>> - fpu_foo,
>> - fpu_fos,
>> - fpu_mxcsr,
>> - fpu_stmm0,
>> - fpu_stmm1,
>> - fpu_stmm2,
>> - fpu_stmm3,
>> - fpu_stmm4,
>> - fpu_stmm5,
>> - fpu_stmm6,
>> - fpu_stmm7,
>> - fpu_xmm0,
>> - fpu_xmm1,
>> - fpu_xmm2,
>> - fpu_xmm3,
>> - fpu_xmm4,
>> - fpu_xmm5,
>> - fpu_xmm6,
>> - fpu_xmm7,
>> -};
>> -
>> -static const RegisterSet
>> -g_reg_sets[k_num_register_sets] =
>> -{
>> - { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
>> - { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }
>> -};
>> -
>> -// Computes the offset of the given GPR in the user data area.
>> -#define GPR_OFFSET(regname) \
>> - (offsetof(RegisterContextLinux_i386::UserArea, regs) + \
>> - offsetof(RegisterContextLinux_i386::GPR, regname))
>> -
>> -// Computes the offset of the given FPR in the user data area.
>> -#define FPR_OFFSET(regname) \
>> - (offsetof(RegisterContextLinux_i386::UserArea, i387) + \
>> - offsetof(RegisterContextLinux_i386::FPU, regname))
>> -
>> -// Number of bytes needed to represent a GPR.
>> -#define GPR_SIZE(reg) sizeof(((RegisterContextLinux_i386::GPR*)NULL)->reg)
>> -
>> -// Number of bytes needed to represent a FPR.
>> -#define FPR_SIZE(reg) sizeof(((RegisterContextLinux_i386::FPU*)NULL)->reg)
>> -
>> -// Number of bytes needed to represent the i'th FP register.
>> -#define FP_SIZE sizeof(((RegisterContextLinux_i386::MMSReg*)NULL)->bytes)
>> -
>> -// Number of bytes needed to represent an XMM register.
>> -#define XMM_SIZE sizeof(RegisterContextLinux_i386::XMMReg)
>> -
>> -#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
>> - { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
>> - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg } }
>> -
>> -#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \
>> - { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
>> - eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg } }
>> -
>> -#define DEFINE_FP(reg, i) \
>> - { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
>> - eFormatVectorOfUInt8, \
>> - { dwarf_##reg##i, dwarf_##reg##i, \
>> - LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } }
>> -
>> -#define DEFINE_XMM(reg, i) \
>> - { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
>> - eFormatVectorOfUInt8, \
>> - { dwarf_##reg##i, dwarf_##reg##i, \
>> - LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } }
>> -
>> -static RegisterInfo
>> -g_register_infos[k_num_registers] =
>> -{
>> - // General purpose registers.
>> - DEFINE_GPR(eax, NULL, gcc_eax, dwarf_eax, LLDB_INVALID_REGNUM, gdb_eax),
>> - DEFINE_GPR(ebx, NULL, gcc_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, gdb_ebx),
>> - DEFINE_GPR(ecx, NULL, gcc_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, gdb_ecx),
>> - DEFINE_GPR(edx, NULL, gcc_edx, dwarf_edx, LLDB_INVALID_REGNUM, gdb_edx),
>> - DEFINE_GPR(edi, NULL, gcc_edi, dwarf_edi, LLDB_INVALID_REGNUM, gdb_edi),
>> - DEFINE_GPR(esi, NULL, gcc_esi, dwarf_esi, LLDB_INVALID_REGNUM, gdb_esi),
>> - DEFINE_GPR(ebp, "fp", gcc_ebp, dwarf_ebp, LLDB_INVALID_REGNUM, gdb_ebp),
>> - DEFINE_GPR(esp, "sp", gcc_esp, dwarf_esp, LLDB_INVALID_REGNUM, gdb_esp),
>> - DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ss),
>> - DEFINE_GPR(eflags, "flags", gcc_eflags, dwarf_eflags, LLDB_INVALID_REGNUM, gdb_eflags),
>> - DEFINE_GPR(eip, "pc", gcc_eip, dwarf_eip, LLDB_INVALID_REGNUM, gdb_eip),
>> - DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_cs),
>> - DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ds),
>> - DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_es),
>> - DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fs),
>> - DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gs),
>> -
>> - // Floating point registers.
>> - DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fcw),
>> - DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fsw),
>> - DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ftw),
>> - DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fop),
>> - DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ip),
>> - DEFINE_FPR(cs, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs),
>> - DEFINE_FPR(foo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_dp),
>> - DEFINE_FPR(fos, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds),
>> - DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_mxcsr),
>> -
>> - DEFINE_FP(stmm, 0),
>> - DEFINE_FP(stmm, 1),
>> - DEFINE_FP(stmm, 2),
>> - DEFINE_FP(stmm, 3),
>> - DEFINE_FP(stmm, 4),
>> - DEFINE_FP(stmm, 5),
>> - DEFINE_FP(stmm, 6),
>> - DEFINE_FP(stmm, 7),
>> -
>> - // XMM registers
>> - DEFINE_XMM(xmm, 0),
>> - DEFINE_XMM(xmm, 1),
>> - DEFINE_XMM(xmm, 2),
>> - DEFINE_XMM(xmm, 3),
>> - DEFINE_XMM(xmm, 4),
>> - DEFINE_XMM(xmm, 5),
>> - DEFINE_XMM(xmm, 6),
>> - DEFINE_XMM(xmm, 7),
>> -
>> -};
>> -
>> -#ifndef NDEBUG
>> -static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
>> -#endif
>> -
>> -static unsigned GetRegOffset(unsigned reg)
>> -{
>> - assert(reg < k_num_registers && "Invalid register number.");
>> - return g_register_infos[reg].byte_offset;
>> -}
>> -
>> -#if 0 // These functions are currently not in use.
>> -static unsigned GetRegSize(unsigned reg)
>> -{
>> - assert(reg < k_num_registers && "Invalid register number.");
>> - return g_register_infos[reg].byte_size;
>> -}
>> -
>> -static bool IsGPR(unsigned reg)
>> -{
>> - return reg <= k_last_gpr; // GPR's come first.
>> -}
>> -
>> -static bool IsFPR(unsigned reg)
>> -{
>> - return (k_first_fpr <= reg && reg <= k_last_fpr);
>> -}
>> -#endif
>> -
>> -
>> -RegisterContextLinux_i386::RegisterContextLinux_i386(Thread &thread,
>> - uint32_t concrete_frame_idx)
>> - : RegisterContextLinux(thread, concrete_frame_idx)
>> -{
>> -}
>> -
>> -RegisterContextLinux_i386::~RegisterContextLinux_i386()
>> -{
>> -}
>> -
>> -ProcessMonitor &
>> -RegisterContextLinux_i386::GetMonitor()
>> -{
>> - ProcessLinux *process = static_cast<ProcessLinux*>(CalculateProcess());
>> - return process->GetMonitor();
>> -}
>> -
>> -void
>> -RegisterContextLinux_i386::Invalidate()
>> -{
>> -}
>> -
>> -void
>> -RegisterContextLinux_i386::InvalidateAllRegisters()
>> -{
>> -}
>> -
>> -size_t
>> -RegisterContextLinux_i386::GetRegisterCount()
>> -{
>> - assert(k_num_register_infos == k_num_registers);
>> - return k_num_registers;
>> -}
>> -
>> -const RegisterInfo *
>> -RegisterContextLinux_i386::GetRegisterInfoAtIndex(uint32_t reg)
>> -{
>> - assert(k_num_register_infos == k_num_registers);
>> - if (reg < k_num_registers)
>> - return &g_register_infos[reg];
>> - else
>> - return NULL;
>> -}
>> -
>> -size_t
>> -RegisterContextLinux_i386::GetRegisterSetCount()
>> -{
>> - return k_num_register_sets;
>> -}
>> -
>> -const RegisterSet *
>> -RegisterContextLinux_i386::GetRegisterSet(uint32_t set)
>> -{
>> - if (set < k_num_register_sets)
>> - return &g_reg_sets[set];
>> - else
>> - return NULL;
>> -}
>> -
>> -unsigned
>> -RegisterContextLinux_i386::GetRegisterIndexFromOffset(unsigned offset)
>> -{
>> - unsigned reg;
>> - for (reg = 0; reg < k_num_registers; reg++)
>> - {
>> - if (g_register_infos[reg].byte_offset == offset)
>> - break;
>> - }
>> - assert(reg < k_num_registers && "Invalid register offset.");
>> - return reg;
>> -}
>> -
>> -const char *
>> -RegisterContextLinux_i386::GetRegisterName(unsigned reg)
>> -{
>> - assert(reg < k_num_registers && "Invalid register offset.");
>> - return g_register_infos[reg].name;
>> -}
>> -
>> -bool
>> -RegisterContextLinux_i386::ReadRegister(const RegisterInfo *reg_info,
>> - RegisterValue &value)
>> -{
>> - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
>> - ProcessMonitor &monitor = GetMonitor();
>> - return monitor.ReadRegisterValue(GetRegOffset(reg), value);
>> -}
>> -
>> -bool
>> -RegisterContextLinux_i386::ReadAllRegisterValues(DataBufferSP &data_sp)
>> -{
>> - return false;
>> -}
>> -
>> -bool RegisterContextLinux_i386::WriteRegister(const RegisterInfo *reg_info,
>> - const RegisterValue &value)
>> -{
>> - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
>> - ProcessMonitor &monitor = GetMonitor();
>> - return monitor.WriteRegisterValue(GetRegOffset(reg), value);
>> -}
>> -
>> -bool
>> -RegisterContextLinux_i386::WriteAllRegisterValues(const DataBufferSP &data)
>> -{
>> - return false;
>> -}
>> -
>> -bool
>> -RegisterContextLinux_i386::UpdateAfterBreakpoint()
>> -{
>> - // PC points one byte past the int3 responsible for the breakpoint.
>> - lldb::addr_t pc;
>> -
>> - if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
>> - return false;
>> -
>> - SetPC(pc - 1);
>> - return true;
>> -}
>> -
>> -uint32_t
>> -RegisterContextLinux_i386::ConvertRegisterKindToRegisterNumber(uint32_t kind,
>> - uint32_t num)
>> -{
>> - if (kind == eRegisterKindGeneric)
>> - {
>> - switch (num)
>> - {
>> - case LLDB_REGNUM_GENERIC_PC: return gpr_eip;
>> - case LLDB_REGNUM_GENERIC_SP: return gpr_esp;
>> - case LLDB_REGNUM_GENERIC_FP: return gpr_ebp;
>> - case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags;
>> - case LLDB_REGNUM_GENERIC_RA:
>> - default:
>> - return LLDB_INVALID_REGNUM;
>> - }
>> - }
>> -
>> - if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
>> - {
>> - switch (num)
>> - {
>> - case dwarf_eax: return gpr_eax;
>> - case dwarf_edx: return gpr_edx;
>> - case dwarf_ecx: return gpr_ecx;
>> - case dwarf_ebx: return gpr_ebx;
>> - case dwarf_esi: return gpr_esi;
>> - case dwarf_edi: return gpr_edi;
>> - case dwarf_ebp: return gpr_ebp;
>> - case dwarf_esp: return gpr_esp;
>> - case dwarf_eip: return gpr_eip;
>> - case dwarf_xmm0: return fpu_xmm0;
>> - case dwarf_xmm1: return fpu_xmm1;
>> - case dwarf_xmm2: return fpu_xmm2;
>> - case dwarf_xmm3: return fpu_xmm3;
>> - case dwarf_xmm4: return fpu_xmm4;
>> - case dwarf_xmm5: return fpu_xmm5;
>> - case dwarf_xmm6: return fpu_xmm6;
>> - case dwarf_xmm7: return fpu_xmm7;
>> - case dwarf_stmm0: return fpu_stmm0;
>> - case dwarf_stmm1: return fpu_stmm1;
>> - case dwarf_stmm2: return fpu_stmm2;
>> - case dwarf_stmm3: return fpu_stmm3;
>> - case dwarf_stmm4: return fpu_stmm4;
>> - case dwarf_stmm5: return fpu_stmm5;
>> - case dwarf_stmm6: return fpu_stmm6;
>> - case dwarf_stmm7: return fpu_stmm7;
>> - default:
>> - return LLDB_INVALID_REGNUM;
>> - }
>> - }
>> -
>> - if (kind == eRegisterKindGDB)
>> - {
>> - switch (num)
>> - {
>> - case gdb_eax : return gpr_eax;
>> - case gdb_ebx : return gpr_ebx;
>> - case gdb_ecx : return gpr_ecx;
>> - case gdb_edx : return gpr_edx;
>> - case gdb_esi : return gpr_esi;
>> - case gdb_edi : return gpr_edi;
>> - case gdb_ebp : return gpr_ebp;
>> - case gdb_esp : return gpr_esp;
>> - case gdb_eip : return gpr_eip;
>> - case gdb_eflags : return gpr_eflags;
>> - case gdb_cs : return gpr_cs;
>> - case gdb_ss : return gpr_ss;
>> - case gdb_ds : return gpr_ds;
>> - case gdb_es : return gpr_es;
>> - case gdb_fs : return gpr_fs;
>> - case gdb_gs : return gpr_gs;
>> - case gdb_stmm0 : return fpu_stmm0;
>> - case gdb_stmm1 : return fpu_stmm1;
>> - case gdb_stmm2 : return fpu_stmm2;
>> - case gdb_stmm3 : return fpu_stmm3;
>> - case gdb_stmm4 : return fpu_stmm4;
>> - case gdb_stmm5 : return fpu_stmm5;
>> - case gdb_stmm6 : return fpu_stmm6;
>> - case gdb_stmm7 : return fpu_stmm7;
>> - case gdb_fcw : return fpu_fcw;
>> - case gdb_fsw : return fpu_fsw;
>> - case gdb_ftw : return fpu_ftw;
>> - case gdb_fpu_cs : return fpu_cs;
>> - case gdb_ip : return fpu_ip;
>> - case gdb_fpu_ds : return fpu_fos;
>> - case gdb_dp : return fpu_foo;
>> - case gdb_fop : return fpu_fop;
>> - case gdb_xmm0 : return fpu_xmm0;
>> - case gdb_xmm1 : return fpu_xmm1;
>> - case gdb_xmm2 : return fpu_xmm2;
>> - case gdb_xmm3 : return fpu_xmm3;
>> - case gdb_xmm4 : return fpu_xmm4;
>> - case gdb_xmm5 : return fpu_xmm5;
>> - case gdb_xmm6 : return fpu_xmm6;
>> - case gdb_xmm7 : return fpu_xmm7;
>> - case gdb_mxcsr : return fpu_mxcsr;
>> - default:
>> - return LLDB_INVALID_REGNUM;
>> - }
>> - }
>> - else if (kind == eRegisterKindLLDB)
>> - {
>> - return num;
>> - }
>> -
>> - return LLDB_INVALID_REGNUM;
>> -}
>> -
>> -bool
>> -RegisterContextLinux_i386::HardwareSingleStep(bool enable)
>> -{
>> - enum { TRACE_BIT = 0x100 };
>> - uint64_t eflags;
>> -
>> - if ((eflags = ReadRegisterAsUnsigned(gpr_eflags, -1UL)) == -1UL)
>> - return false;
>> -
>> - if (enable)
>> - {
>> - if (eflags & TRACE_BIT)
>> - return true;
>> -
>> - eflags |= TRACE_BIT;
>> - }
>> - else
>> - {
>> - if (!(eflags & TRACE_BIT))
>> - return false;
>> -
>> - eflags &= ~TRACE_BIT;
>> - }
>> -
>> - return WriteRegisterFromUnsigned(gpr_eflags, eflags);
>> -}
>> -
>> -void
>> -RegisterContextLinux_i386::LogGPR(const char *title)
>> -{
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_REGISTERS));
>> - if (log)
>> - {
>> - if (title)
>> - log->Printf ("%s", title);
>> - for (uint32_t i=0; i<k_num_gpr_registers; i++)
>> - {
>> - uint32_t reg = gpr_eax + i;
>> - log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&user.regs)[reg]);
>> - }
>> - }
>> -}
>> -
>> -bool
>> -RegisterContextLinux_i386::ReadGPR()
>> -{
>> - bool result;
>> -
>> - ProcessMonitor &monitor = GetMonitor();
>> - result = monitor.ReadGPR(&user.regs);
>> - LogGPR("RegisterContextLinux_i386::ReadGPR()");
>> - return result;
>> -}
>> -
>> -bool
>> -RegisterContextLinux_i386::ReadFPR()
>> -{
>> - ProcessMonitor &monitor = GetMonitor();
>> - return monitor.ReadFPR(&user.i387);
>> -}
>> Index: source/Plugins/Process/Linux/ProcessMessage.cpp
>> ===================================================================
>> --- source/Plugins/Process/Linux/ProcessMessage.cpp (revision 147560)
>> +++ source/Plugins/Process/Linux/ProcessMessage.cpp (working copy)
>> @@ -1,245 +0,0 @@
>> -//===-- ProcessMessage.cpp --------------------------------------*- C++ -*-===//
>> -//
>> -// The LLVM Compiler Infrastructure
>> -//
>> -// This file is distributed under the University of Illinois Open Source
>> -// License. See LICENSE.TXT for details.
>> -//
>> -//===----------------------------------------------------------------------===//
>> -
>> -#include "ProcessMessage.h"
>> -
>> -using namespace lldb_private;
>> -
>> -const char *
>> -ProcessMessage::GetCrashReasonString(CrashReason reason)
>> -{
>> - const char *str = NULL;
>> -
>> - switch (reason)
>> - {
>> - default:
>> - assert(false && "invalid CrashReason");
>> - break;
>> -
>> - case eInvalidAddress:
>> - str = "invalid address";
>> - break;
>> - case ePrivilegedAddress:
>> - str = "address access protected";
>> - break;
>> - case eIllegalOpcode:
>> - str = "illegal instruction";
>> - break;
>> - case eIllegalOperand:
>> - str = "illegal instruction operand";
>> - break;
>> - case eIllegalAddressingMode:
>> - str = "illegal addressing mode";
>> - break;
>> - case eIllegalTrap:
>> - str = "illegal trap";
>> - break;
>> - case ePrivilegedOpcode:
>> - str = "privileged instruction";
>> - break;
>> - case ePrivilegedRegister:
>> - str = "privileged register";
>> - break;
>> - case eCoprocessorError:
>> - str = "coprocessor error";
>> - break;
>> - case eInternalStackError:
>> - str = "internal stack error";
>> - break;
>> - case eIllegalAlignment:
>> - str = "illegal alignment";
>> - break;
>> - case eIllegalAddress:
>> - str = "illegal address";
>> - break;
>> - case eHardwareError:
>> - str = "hardware error";
>> - break;
>> - case eIntegerDivideByZero:
>> - str = "integer divide by zero";
>> - break;
>> - case eIntegerOverflow:
>> - str = "integer overflow";
>> - break;
>> - case eFloatDivideByZero:
>> - str = "floating point divide by zero";
>> - break;
>> - case eFloatOverflow:
>> - str = "floating point overflow";
>> - break;
>> - case eFloatUnderflow:
>> - str = "floating point underflow";
>> - break;
>> - case eFloatInexactResult:
>> - str = "inexact floating point result";
>> - break;
>> - case eFloatInvalidOperation:
>> - str = "invalid floating point operation";
>> - break;
>> - case eFloatSubscriptRange:
>> - str = "invalid floating point subscript range";
>> - break;
>> - }
>> -
>> - return str;
>> -}
>> -
>> -const char *
>> -ProcessMessage::PrintCrashReason(CrashReason reason)
>> -{
>> -#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
>> - // Just return the code in asci for integration builds.
>> - chcar str[8];
>> - sprintf(str, "%d", reason);
>> -#else
>> - const char *str = NULL;
>> -
>> - switch (reason)
>> - {
>> - default:
>> - assert(false && "invalid CrashReason");
>> - break;
>> -
>> - case eInvalidCrashReason:
>> - str = "eInvalidCrashReason";
>> - break;
>> -
>> - // SIGSEGV crash rcase easons.
>> - case eInvalidAddress:
>> - str = "eInvalidAddress";
>> - break;
>> - case ePrivilegedAddress:
>> - str = "ePrivilegedAddress";
>> - break;
>> -
>> - // SIGILL crash rcase easons.
>> - case eIllegalOpcode:
>> - str = "eIllegalOpcode";
>> - break;
>> - case eIllegalOperand:
>> - str = "eIllegalOperand";
>> - break;
>> - case eIllegalAddressingMode:
>> - str = "eIllegalAddressingMode";
>> - break;
>> - case eIllegalTrap:
>> - str = "eIllegalTrap";
>> - break;
>> - case ePrivilegedOpcode:
>> - str = "ePrivilegedOpcode";
>> - break;
>> - case ePrivilegedRegister:
>> - str = "ePrivilegedRegister";
>> - break;
>> - case eCoprocessorError:
>> - str = "eCoprocessorError";
>> - break;
>> - case eInternalStackError:
>> - str = "eInternalStackError";
>> - break;
>> -
>> - // SIGBUS crash rcase easons:
>> - case eIllegalAlignment:
>> - str = "eIllegalAlignment";
>> - break;
>> - case eIllegalAddress:
>> - str = "eIllegalAddress";
>> - break;
>> - case eHardwareError:
>> - str = "eHardwareError";
>> - break;
>> -
>> - // SIGFPE crash rcase easons:
>> - case eIntegerDivideByZero:
>> - str = "eIntegerDivideByZero";
>> - break;
>> - case eIntegerOverflow:
>> - str = "eIntegerOverflow";
>> - break;
>> - case eFloatDivideByZero:
>> - str = "eFloatDivideByZero";
>> - break;
>> - case eFloatOverflow:
>> - str = "eFloatOverflow";
>> - break;
>> - case eFloatUnderflow:
>> - str = "eFloatUnderflow";
>> - break;
>> - case eFloatInexactResult:
>> - str = "eFloatInexactResult";
>> - break;
>> - case eFloatInvalidOperation:
>> - str = "eFloatInvalidOperation";
>> - break;
>> - case eFloatSubscriptRange:
>> - str = "eFloatSubscriptRange";
>> - break;
>> - }
>> -#endif
>> -
>> - return str;
>> -}
>> -
>> -const char *
>> -ProcessMessage::PrintCrashReason() const
>> -{
>> - return PrintCrashReason(m_crash_reason);
>> -}
>> -
>> -const char *
>> -ProcessMessage::PrintKind(Kind kind)
>> -{
>> -#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
>> - // Just return the code in asci for integration builds.
>> - chcar str[8];
>> - sprintf(str, "%d", reason);
>> -#else
>> - const char *str = NULL;
>> -
>> - switch (kind)
>> - {
>> - default:
>> - assert(false && "invalid Kind");
>> - break;
>> -
>> - case eInvalidMessage:
>> - str = "eInvalidMessage";
>> - break;
>> - case eExitMessage:
>> - str = "eExitMessage";
>> - break;
>> - case eLimboMessage:
>> - str = "eLimboMessage";
>> - break;
>> - case eSignalMessage:
>> - str = "eSignalMessage";
>> - break;
>> - case eSignalDeliveredMessage:
>> - str = "eSignalDeliveredMessage";
>> - break;
>> - case eTraceMessage:
>> - str = "eTraceMessage";
>> - break;
>> - case eBreakpointMessage:
>> - str = "eBreakpointMessage";
>> - break;
>> - case eCrashMessage:
>> - str = "eCrashMessage";
>> - break;
>> - }
>> -#endif
>> -
>> - return str;
>> -}
>> -
>> -const char *
>> -ProcessMessage::PrintKind() const
>> -{
>> - return PrintKind(m_kind);
>> -}
>> Index: source/Plugins/Process/Linux/ProcessMonitor.cpp
>> ===================================================================
>> --- source/Plugins/Process/Linux/ProcessMonitor.cpp (revision 147560)
>> +++ 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<ProcessLinux *>(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<ProcessLinux *>(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)
>> @@ -1101,11 +1101,10 @@
>> if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
>> goto FINISH;
>>
>> - // Update the process thread list with this new thread and mark it as
>> - // current.
>> + // Update the process thread list with this new thread.
>> // 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);
>> @@ -1167,9 +1166,8 @@
>>
>> ProcessMonitor *monitor = args->m_monitor;
>> ProcessLinux &process = monitor->GetProcess();
>> -
>> lldb::ThreadSP inferior;
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS));
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
>>
>> if (pid <= 1)
>> {
>> @@ -1192,13 +1190,11 @@
>> goto FINISH;
>> }
>>
>> - // Update the process thread list with the attached thread and
>> - // mark it as current.
>> - inferior.reset(new LinuxThread(process, pid));
>> + // Update the process thread list with the attached thread.
>> + inferior.reset(new POSIXThread(process, pid));
>> if (log)
>> log->Printf ("ProcessMonitor::%s() adding tid = %i", __FUNCTION__, pid);
>> process.GetThreadList().AddThread(inferior);
>> - process.GetThreadList().SetSelectedThreadByID(pid);
>>
>> // Let our process instance know the thread has stopped.
>> process.SendMessage(ProcessMessage::Trace(pid));
>> @@ -1568,7 +1564,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/LinuxStopInfo.h
>> ===================================================================
>> --- source/Plugins/Process/Linux/LinuxStopInfo.h (revision 147560)
>> +++ source/Plugins/Process/Linux/LinuxStopInfo.h (working copy)
>> @@ -1,92 +0,0 @@
>> -//===-- LinuxStopInfo.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_LinuxStopInfo_H_
>> -#define liblldb_LinuxStopInfo_H_
>> -
>> -// C Includes
>> -// C++ Includes
>> -// Other libraries and framework includes
>> -// Project includes
>> -#include "lldb/Target/StopInfo.h"
>> -
>> -#include "LinuxThread.h"
>> -#include "ProcessMessage.h"
>> -
>> -//===----------------------------------------------------------------------===//
>> -/// @class LinuxStopInfo
>> -/// @brief Simple base class for all Linux-specific StopInfo objects.
>> -///
>> -class LinuxStopInfo
>> - : public lldb_private::StopInfo
>> -{
>> -public:
>> - LinuxStopInfo(lldb_private::Thread &thread, uint32_t status)
>> - : StopInfo(thread, status)
>> - { }
>> -};
>> -
>> -//===----------------------------------------------------------------------===//
>> -/// @class LinuxLimboStopInfo
>> -/// @brief Represents the stop state of a process ready to exit.
>> -///
>> -class LinuxLimboStopInfo
>> - : public LinuxStopInfo
>> -{
>> -public:
>> - LinuxLimboStopInfo(LinuxThread &thread)
>> - : LinuxStopInfo(thread, 0)
>> - { }
>> -
>> - ~LinuxLimboStopInfo();
>> -
>> - lldb::StopReason
>> - GetStopReason() const;
>> -
>> - const char *
>> - GetDescription();
>> -
>> - bool
>> - ShouldStop(lldb_private::Event *event_ptr);
>> -
>> - bool
>> - ShouldNotify(lldb_private::Event *event_ptr);
>> -};
>> -
>> -
>> -//===----------------------------------------------------------------------===//
>> -/// @class LinuxCrashStopInfo
>> -/// @brief Represents the stop state of process that is ready to crash.
>> -///
>> -class LinuxCrashStopInfo
>> - : public LinuxStopInfo
>> -{
>> -public:
>> - LinuxCrashStopInfo(LinuxThread &thread, uint32_t status,
>> - ProcessMessage::CrashReason reason)
>> - : LinuxStopInfo(thread, status),
>> - m_crash_reason(reason)
>> - { }
>> -
>> - ~LinuxCrashStopInfo();
>> -
>> - lldb::StopReason
>> - GetStopReason() const;
>> -
>> - const char *
>> - GetDescription();
>> -
>> - ProcessMessage::CrashReason
>> - GetCrashReason() const;
>> -
>> -private:
>> - ProcessMessage::CrashReason m_crash_reason;
>> -};
>> -
>> -#endif
>> Index: source/Plugins/Process/Linux/LinuxThread.cpp
>> ===================================================================
>> --- source/Plugins/Process/Linux/LinuxThread.cpp (revision 147560)
>> +++ source/Plugins/Process/Linux/LinuxThread.cpp (working copy)
>> @@ -1,350 +0,0 @@
>> -//===-- LinuxThread.cpp -----------------------------------------*- C++ -*-===//
>> -//
>> -// The LLVM Compiler Infrastructure
>> -//
>> -// This file is distributed under the University of Illinois Open Source
>> -// License. See LICENSE.TXT for details.
>> -//
>> -//===----------------------------------------------------------------------===//
>> -
>> -// C Includes
>> -#include <errno.h>
>> -
>> -// C++ Includes
>> -// Other libraries and framework includes
>> -// Project includes
>> -#include "lldb/Core/Debugger.h"
>> -#include "lldb/Host/Host.h"
>> -#include "lldb/Target/Process.h"
>> -#include "lldb/Target/StopInfo.h"
>> -#include "lldb/Target/Target.h"
>> -#include "LinuxStopInfo.h"
>> -#include "LinuxThread.h"
>> -#include "ProcessLinux.h"
>> -#include "ProcessLinuxLog.h"
>> -#include "ProcessMonitor.h"
>> -#include "RegisterContextLinux_i386.h"
>> -#include "RegisterContextLinux_x86_64.h"
>> -#include "UnwindLLDB.h"
>> -
>> -using namespace lldb_private;
>> -
>> -
>> -LinuxThread::LinuxThread(Process &process, lldb::tid_t tid)
>> - : Thread(process, tid),
>> - m_frame_ap(0)
>> -{
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
>> - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE))
>> - log->Printf ("LinuxThread::%s (tid = %i)", __FUNCTION__, tid);
>> -}
>> -
>> -LinuxThread::~LinuxThread()
>> -{
>> - DestroyThread();
>> -}
>> -
>> -ProcessMonitor &
>> -LinuxThread::GetMonitor()
>> -{
>> - ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
>> - return process.GetMonitor();
>> -}
>> -
>> -void
>> -LinuxThread::RefreshStateAfterStop()
>> -{
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
>> - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE))
>> - log->Printf ("LinuxThread::%s ()", __FUNCTION__);
>> -
>> - // Let all threads recover from stopping and do any clean up based
>> - // on the previous thread state (if any).
>> - ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
>> - process.GetThreadList().RefreshStateAfterStop();
>> -}
>> -
>> -const char *
>> -LinuxThread::GetInfo()
>> -{
>> - return NULL;
>> -}
>> -
>> -lldb::RegisterContextSP
>> -LinuxThread::GetRegisterContext()
>> -{
>> - if (!m_reg_context_sp)
>> - {
>> - ArchSpec arch = Host::GetArchitecture();
>> -
>> - switch (arch.GetCore())
>> - {
>> - default:
>> - assert(false && "CPU type not supported!");
>> - break;
>> -
>> - case ArchSpec::eCore_x86_32_i386:
>> - case ArchSpec::eCore_x86_32_i486:
>> - case ArchSpec::eCore_x86_32_i486sx:
>> - m_reg_context_sp.reset(new RegisterContextLinux_i386(*this, 0));
>> - break;
>> -
>> - case ArchSpec::eCore_x86_64_x86_64:
>> - m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0));
>> - break;
>> - }
>> - }
>> - return m_reg_context_sp;
>> -}
>> -
>> -lldb::RegisterContextSP
>> -LinuxThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
>> -{
>> - lldb::RegisterContextSP reg_ctx_sp;
>> - uint32_t concrete_frame_idx = 0;
>> -
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
>> - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE))
>> - log->Printf ("LinuxThread::%s ()", __FUNCTION__);
>> -
>> - if (frame)
>> - concrete_frame_idx = frame->GetConcreteFrameIndex();
>> -
>> - if (concrete_frame_idx == 0)
>> - reg_ctx_sp = GetRegisterContext();
>> - else
>> - {
>> - assert(GetUnwinder());
>> - reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
>> - }
>> -
>> - return reg_ctx_sp;
>> -}
>> -
>> -lldb::StopInfoSP
>> -LinuxThread::GetPrivateStopReason()
>> -{
>> - return m_stop_info;
>> -}
>> -
>> -Unwind *
>> -LinuxThread::GetUnwinder()
>> -{
>> - if (m_unwinder_ap.get() == NULL)
>> - m_unwinder_ap.reset(new UnwindLLDB(*this));
>> -
>> - return m_unwinder_ap.get();
>> -}
>> -
>> -bool
>> -LinuxThread::WillResume(lldb::StateType resume_state)
>> -{
>> - SetResumeState(resume_state);
>> -
>> - ClearStackFrames();
>> - if (m_unwinder_ap.get())
>> - m_unwinder_ap->Clear();
>> -
>> - return Thread::WillResume(resume_state);
>> -}
>> -
>> -bool
>> -LinuxThread::Resume()
>> -{
>> - lldb::StateType resume_state = GetResumeState();
>> - ProcessMonitor &monitor = GetMonitor();
>> - bool status;
>> -
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
>> - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE))
>> - log->Printf ("LinuxThread::%s ()", __FUNCTION__);
>> -
>> - switch (resume_state)
>> - {
>> - default:
>> - assert(false && "Unexpected state for resume!");
>> - status = false;
>> - break;
>> -
>> - case lldb::eStateRunning:
>> - SetState(resume_state);
>> - status = monitor.Resume(GetID(), GetResumeSignal());
>> - break;
>> -
>> - case lldb::eStateStepping:
>> - SetState(resume_state);
>> - status = monitor.SingleStep(GetID(), GetResumeSignal());
>> - break;
>> - }
>> -
>> - return status;
>> -}
>> -
>> -void
>> -LinuxThread::Notify(const ProcessMessage &message)
>> -{
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
>> - if (log)
>> - log->Printf ("LinuxThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind());
>> -
>> - switch (message.GetKind())
>> - {
>> - default:
>> - assert(false && "Unexpected message kind!");
>> - break;
>> -
>> - case ProcessMessage::eLimboMessage:
>> - LimboNotify(message);
>> - break;
>> -
>> - case ProcessMessage::eSignalMessage:
>> - SignalNotify(message);
>> - break;
>> -
>> - case ProcessMessage::eSignalDeliveredMessage:
>> - SignalDeliveredNotify(message);
>> - break;
>> -
>> - case ProcessMessage::eTraceMessage:
>> - TraceNotify(message);
>> - break;
>> -
>> - case ProcessMessage::eBreakpointMessage:
>> - BreakNotify(message);
>> - break;
>> -
>> - case ProcessMessage::eCrashMessage:
>> - CrashNotify(message);
>> - break;
>> - }
>> -}
>> -
>> -void
>> -LinuxThread::BreakNotify(const ProcessMessage &message)
>> -{
>> - bool status;
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
>> -
>> - assert(GetRegisterContextLinux());
>> - status = GetRegisterContextLinux()->UpdateAfterBreakpoint();
>> - assert(status && "Breakpoint update failed!");
>> -
>> - // With our register state restored, resolve the breakpoint object
>> - // corresponding to our current PC.
>> - assert(GetRegisterContext());
>> - lldb::addr_t pc = GetRegisterContext()->GetPC();
>> - if (log)
>> - log->Printf ("LinuxThread::%s () PC=0x%8.8llx", __FUNCTION__, pc);
>> - lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc));
>> - assert(bp_site);
>> - lldb::break_id_t bp_id = bp_site->GetID();
>> - assert(bp_site && bp_site->ValidForThisThread(this));
>> -
>> -
>> - m_breakpoint = bp_site;
>> - m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id);
>> -}
>> -
>> -void
>> -LinuxThread::TraceNotify(const ProcessMessage &message)
>> -{
>> - m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
>> -}
>> -
>> -void
>> -LinuxThread::LimboNotify(const ProcessMessage &message)
>> -{
>> - m_stop_info = lldb::StopInfoSP(new LinuxLimboStopInfo(*this));
>> -}
>> -
>> -void
>> -LinuxThread::SignalNotify(const ProcessMessage &message)
>> -{
>> - int signo = message.GetSignal();
>> -
>> - m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
>> - SetResumeSignal(signo);
>> -}
>> -
>> -void
>> -LinuxThread::SignalDeliveredNotify(const ProcessMessage &message)
>> -{
>> - int signo = message.GetSignal();
>> -
>> - // Just treat debugger generated signal events like breakpoints for now.
>> - m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
>> - SetResumeSignal(signo);
>> -}
>> -
>> -void
>> -LinuxThread::CrashNotify(const ProcessMessage &message)
>> -{
>> - int signo = message.GetSignal();
>> -
>> - assert(message.GetKind() == ProcessMessage::eCrashMessage);
>> -
>> - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
>> - if (log)
>> - log->Printf ("LinuxThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason());
>> -
>> - m_stop_info = lldb::StopInfoSP(new LinuxCrashStopInfo(
>> - *this, signo, message.GetCrashReason()));
>> - SetResumeSignal(signo);
>> -}
>> -
>> -unsigned
>> -LinuxThread::GetRegisterIndexFromOffset(unsigned offset)
>> -{
>> - unsigned reg;
>> - ArchSpec arch = Host::GetArchitecture();
>> -
>> - switch (arch.GetCore())
>> - {
>> - default:
>> - assert(false && "CPU type not supported!");
>> - break;
>> -
>> - case ArchSpec::eCore_x86_32_i386:
>> - case ArchSpec::eCore_x86_32_i486:
>> - case ArchSpec::eCore_x86_32_i486sx:
>> - reg = RegisterContextLinux_i386::GetRegisterIndexFromOffset(offset);
>> - break;
>> -
>> - case ArchSpec::eCore_x86_64_x86_64:
>> - reg = RegisterContextLinux_x86_64::GetRegisterIndexFromOffset(offset);
>> - break;
>> - }
>> - return reg;
>> -}
>> -
>> -const char *
>> -LinuxThread::GetRegisterName(unsigned reg)
>> -{
>> - const char * name;
>> - ArchSpec arch = Host::GetArchitecture();
>> -
>> - switch (arch.GetCore())
>> - {
>> - default:
>> - assert(false && "CPU type not supported!");
>> - break;
>> -
>> - case ArchSpec::eCore_x86_32_i386:
>> - case ArchSpec::eCore_x86_32_i486:
>> - case ArchSpec::eCore_x86_32_i486sx:
>> - name = RegisterContextLinux_i386::GetRegisterName(reg);
>> - break;
>> -
>> - case ArchSpec::eCore_x86_64_x86_64:
>> - name = RegisterContextLinux_x86_64::GetRegisterName(reg);
>> - break;
>> - }
>> - return name;
>> -}
>> -
>> -const char *
>> -LinuxThread::GetRegisterNameFromOffset(unsigned offset)
>> -{
>> - return GetRegisterName(GetRegisterIndexFromOffset(offset));
>> -}
>> -
>> Index: source/Plugins/Process/Linux/RegisterContextLinux_i386.h
>> ===================================================================
>> --- source/Plugins/Process/Linux/RegisterContextLinux_i386.h (revision 147560)
>> +++ source/Plugins/Process/Linux/RegisterContextLinux_i386.h (working copy)
>> @@ -1,169 +0,0 @@
>> -//===-- RegisterContextLinux_i386.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_RegisterContextLinux_i386_h_
>> -#define liblldb_RegisterContextLinux_i386_h_
>> -
>> -// C Includes
>> -// C++ Includes
>> -// Other libraries and framework includes
>> -// Project includes
>> -#include "lldb/Core/Log.h"
>> -#include "RegisterContextLinux.h"
>> -
>> -class RegisterContextLinux_i386 : public RegisterContextLinux
>> -{
>> -public:
>> - RegisterContextLinux_i386(lldb_private::Thread &thread,
>> - uint32_t concreate_frame_idx);
>> -
>> - ~RegisterContextLinux_i386();
>> -
>> - 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);
>> -
>> -#if 0
>> - bool
>> - ReadRegisterValue(uint32_t reg, lldb_private::Scalar &value);
>> -
>> - bool
>> - ReadRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data);
>> -#endif
>> -
>> - virtual bool
>> - ReadRegister(const lldb_private::RegisterInfo *reg_info,
>> - lldb_private::RegisterValue &value);
>> -
>> - bool
>> - ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
>> -
>> -#if 0
>> - bool
>> - WriteRegisterValue(uint32_t reg, const lldb_private::Scalar &value);
>> -
>> - bool
>> - WriteRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data,
>> - uint32_t data_offset = 0);
>> -#endif
>> -
>> - 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
>> - {
>> - uint32_t ebx;
>> - uint32_t ecx;
>> - uint32_t edx;
>> - uint32_t esi;
>> - uint32_t edi;
>> - uint32_t ebp;
>> - uint32_t eax;
>> - uint32_t ds;
>> - uint32_t es;
>> - uint32_t fs;
>> - uint32_t gs;
>> - uint32_t orig_ax;
>> - uint32_t eip;
>> - uint32_t cs;
>> - uint32_t eflags;
>> - uint32_t esp;
>> - uint32_t ss;
>> - };
>> -
>> - struct MMSReg
>> - {
>> - uint8_t bytes[8];
>> - };
>> -
>> - struct XMMReg
>> - {
>> - uint8_t bytes[16];
>> - };
>> -
>> - struct FPU
>> - {
>> - uint16_t fcw;
>> - uint16_t fsw;
>> - uint16_t ftw;
>> - uint16_t fop;
>> - uint32_t ip;
>> - uint32_t cs;
>> - uint32_t foo;
>> - uint32_t fos;
>> - uint32_t mxcsr;
>> - uint32_t reserved;
>> - MMSReg stmm[8];
>> - XMMReg xmm[8];
>> - uint32_t pad[56];
>> - };
>> -
>> - struct UserArea
>> - {
>> - GPR regs; // General purpose registers.
>> - int32_t fpvalid; // True if FPU is being used.
>> - FPU i387; // FPU registers.
>> - uint32_t tsize; // Text segment size.
>> - uint32_t dsize; // Data segment size.
>> - uint32_t ssize; // Stack segment size.
>> - uint32_t start_code; // VM address of text.
>> - uint32_t start_stack; // VM address of stack bottom (top in rsp).
>> - int32_t signal; // Signal causing core dump.
>> - int32_t reserved; // Unused.
>> - uint32_t ar0; // Location of GPR's.
>> - FPU* fpstate; // Location of FPR's.
>> - uint32_t magic; // Identifier for core dumps.
>> - char u_comm[32]; // Command causing core dump.
>> - uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
>> - };
>> -private:
>> - UserArea user;
>> -
>> - ProcessMonitor &GetMonitor();
>> -
>> - void LogGPR(const char *title);
>> -
>> - bool ReadGPR();
>> - bool ReadFPR();
>> -};
>> -
>> -#endif // #ifndef liblldb_RegisterContextLinux_i386_h_
>> Index: source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp
>> ===================================================================
>> --- source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp (revision 147560)
>> +++ source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp (working copy)
>> @@ -1,759 +0,0 @@
>> -//===-- RegisterContextLinux_x86_64.cpp -------------------------*- C++ -*-===//
>> -//
>> -// The LLVM Compiler Infrastructure
>> -//
>> -// This file is distributed under the University of Illinois Open Source
>> -// License. See LICENSE.TXT for details.
>> -//
>> -//===----------------------------------------------------------------------===//
>> -
>> -#include <cstring>
>> -#include <errno.h>
>> -#include <stdint.h>
>> -
>> -#include "lldb/Core/DataBufferHeap.h"
>> -#include "lldb/Core/DataExtractor.h"
>> -#include "lldb/Core/Scalar.h"
>> -#include "lldb/Target/Thread.h"
>> -#include "lldb/Host/Endian.h"
>> -
>> -#include "ProcessLinux.h"
>> -#include "ProcessMonitor.h"
>> -#include "RegisterContextLinux_x86_64.h"
>> -
>> -using namespace lldb_private;
>> -using namespace lldb;
>> -
>> -// Internal codes for all x86_64 registers.
>> -enum
>> -{
>> - k_first_gpr,
>> - gpr_rax = k_first_gpr,
>> - gpr_rbx,
>> - gpr_rcx,
>> - gpr_rdx,
>> - gpr_rdi,
>> - gpr_rsi,
>> - gpr_rbp,
>> - gpr_rsp,
>> - gpr_r8,
>> - gpr_r9,
>> - gpr_r10,
>> - gpr_r11,
>> - gpr_r12,
>> - gpr_r13,
>> - gpr_r14,
>> - gpr_r15,
>> - gpr_rip,
>> - gpr_rflags,
>> - gpr_cs,
>> - gpr_fs,
>> - gpr_gs,
>> - gpr_ss,
>> - gpr_ds,
>> - gpr_es,
>> - k_last_gpr = gpr_es,
>> -
>> - k_first_fpr,
>> - fpu_fcw = k_first_fpr,
>> - fpu_fsw,
>> - fpu_ftw,
>> - fpu_fop,
>> - fpu_ip,
>> - fpu_cs,
>> - fpu_dp,
>> - fpu_ds,
>> - fpu_mxcsr,
>> - fpu_mxcsrmask,
>> - fpu_stmm0,
>> - fpu_stmm1,
>> - fpu_stmm2,
>> - fpu_stmm3,
>> - fpu_stmm4,
>> - fpu_stmm5,
>> - fpu_stmm6,
>> - fpu_stmm7,
>> - fpu_xmm0,
>> - fpu_xmm1,
>> - fpu_xmm2,
>> - fpu_xmm3,
>> - fpu_xmm4,
>> - fpu_xmm5,
>> - fpu_xmm6,
>> - fpu_xmm7,
>> - fpu_xmm8,
>> - fpu_xmm9,
>> - fpu_xmm10,
>> - fpu_xmm11,
>> - fpu_xmm12,
>> - fpu_xmm13,
>> - fpu_xmm14,
>> - fpu_xmm15,
>> - k_last_fpr = fpu_xmm15,
>> -
>> - k_num_registers,
>> - k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
>> - k_num_fpu_registers = k_last_fpr - k_first_fpr + 1
>> -};
>> -
>> -// Number of register sets provided by this context.
>> -enum
>> -{
>> - k_num_register_sets = 2
>> -};
>> -
>> -enum gcc_dwarf_regnums
>> -{
>> - gcc_dwarf_gpr_rax = 0,
>> - gcc_dwarf_gpr_rdx,
>> - gcc_dwarf_gpr_rcx,
>> - gcc_dwarf_gpr_rbx,
>> - gcc_dwarf_gpr_rsi,
>> - gcc_dwarf_gpr_rdi,
>> - gcc_dwarf_gpr_rbp,
>> - gcc_dwarf_gpr_rsp,
>> - gcc_dwarf_gpr_r8,
>> - gcc_dwarf_gpr_r9,
>> - gcc_dwarf_gpr_r10,
>> - gcc_dwarf_gpr_r11,
>> - gcc_dwarf_gpr_r12,
>> - gcc_dwarf_gpr_r13,
>> - gcc_dwarf_gpr_r14,
>> - gcc_dwarf_gpr_r15,
>> - gcc_dwarf_gpr_rip,
>> - gcc_dwarf_fpu_xmm0,
>> - gcc_dwarf_fpu_xmm1,
>> - gcc_dwarf_fpu_xmm2,
>> - gcc_dwarf_fpu_xmm3,
>> - gcc_dwarf_fpu_xmm4,
>> - gcc_dwarf_fpu_xmm5,
>> - gcc_dwarf_fpu_xmm6,
>> - gcc_dwarf_fpu_xmm7,
>> - gcc_dwarf_fpu_xmm8,
>> - gcc_dwarf_fpu_xmm9,
>> - gcc_dwarf_fpu_xmm10,
>> - gcc_dwarf_fpu_xmm11,
>> - gcc_dwarf_fpu_xmm12,
>> - gcc_dwarf_fpu_xmm13,
>> - gcc_dwarf_fpu_xmm14,
>> - gcc_dwarf_fpu_xmm15,
>> - gcc_dwarf_fpu_stmm0,
>> - gcc_dwarf_fpu_stmm1,
>> - gcc_dwarf_fpu_stmm2,
>> - gcc_dwarf_fpu_stmm3,
>> - gcc_dwarf_fpu_stmm4,
>> - gcc_dwarf_fpu_stmm5,
>> - gcc_dwarf_fpu_stmm6,
>> - gcc_dwarf_fpu_stmm7
>> -};
>> -
>> -enum gdb_regnums
>> -{
>> - gdb_gpr_rax = 0,
>> - gdb_gpr_rbx = 1,
>> - gdb_gpr_rcx = 2,
>> - gdb_gpr_rdx = 3,
>> - gdb_gpr_rsi = 4,
>> - gdb_gpr_rdi = 5,
>> - gdb_gpr_rbp = 6,
>> - gdb_gpr_rsp = 7,
>> - gdb_gpr_r8 = 8,
>> - gdb_gpr_r9 = 9,
>> - gdb_gpr_r10 = 10,
>> - gdb_gpr_r11 = 11,
>> - gdb_gpr_r12 = 12,
>> - gdb_gpr_r13 = 13,
>> - gdb_gpr_r14 = 14,
>> - gdb_gpr_r15 = 15,
>> - gdb_gpr_rip = 16,
>> - gdb_gpr_rflags = 17,
>> - gdb_gpr_cs = 18,
>> - gdb_gpr_ss = 19,
>> - gdb_gpr_ds = 20,
>> - gdb_gpr_es = 21,
>> - gdb_gpr_fs = 22,
>> - gdb_gpr_gs = 23,
>> - gdb_fpu_stmm0 = 24,
>> - gdb_fpu_stmm1 = 25,
>> - gdb_fpu_stmm2 = 26,
>> - gdb_fpu_stmm3 = 27,
>> - gdb_fpu_stmm4 = 28,
>> - gdb_fpu_stmm5 = 29,
>> - gdb_fpu_stmm6 = 30,
>> - gdb_fpu_stmm7 = 31,
>> - gdb_fpu_fcw = 32,
>> - gdb_fpu_fsw = 33,
>> - gdb_fpu_ftw = 34,
>> - gdb_fpu_cs = 35,
>> - gdb_fpu_ip = 36,
>> - gdb_fpu_ds = 37,
>> - gdb_fpu_dp = 38,
>> - gdb_fpu_fop = 39,
>> - gdb_fpu_xmm0 = 40,
>> - gdb_fpu_xmm1 = 41,
>> - gdb_fpu_xmm2 = 42,
>> - gdb_fpu_xmm3 = 43,
>> - gdb_fpu_xmm4 = 44,
>> - gdb_fpu_xmm5 = 45,
>> - gdb_fpu_xmm6 = 46,
>> - gdb_fpu_xmm7 = 47,
>> - gdb_fpu_xmm8 = 48,
>> - gdb_fpu_xmm9 = 49,
>> - gdb_fpu_xmm10 = 50,
>> - gdb_fpu_xmm11 = 51,
>> - gdb_fpu_xmm12 = 52,
>> - gdb_fpu_xmm13 = 53,
>> - gdb_fpu_xmm14 = 54,
>> - gdb_fpu_xmm15 = 55,
>> - gdb_fpu_mxcsr = 56
>> -};
>> -
>> -static const
>> -uint32_t g_gpr_regnums[k_num_gpr_registers] =
>> -{
>> - gpr_rax,
>> - gpr_rbx,
>> - gpr_rcx,
>> - gpr_rdx,
>> - gpr_rdi,
>> - gpr_rsi,
>> - gpr_rbp,
>> - gpr_rsp,
>> - gpr_r8,
>> - gpr_r9,
>> - gpr_r10,
>> - gpr_r11,
>> - gpr_r12,
>> - gpr_r13,
>> - gpr_r14,
>> - gpr_r15,
>> - gpr_rip,
>> - gpr_rflags,
>> - gpr_cs,
>> - gpr_fs,
>> - gpr_gs,
>> - gpr_ss,
>> - gpr_ds,
>> - gpr_es
>> -};
>> -
>> -static const uint32_t
>> -g_fpu_regnums[k_num_fpu_registers] =
>> -{
>> - fpu_fcw,
>> - fpu_fsw,
>> - fpu_ftw,
>> - fpu_fop,
>> - fpu_ip,
>> - fpu_cs,
>> - fpu_dp,
>> - fpu_ds,
>> - fpu_mxcsr,
>> - fpu_mxcsrmask,
>> - fpu_stmm0,
>> - fpu_stmm1,
>> - fpu_stmm2,
>> - fpu_stmm3,
>> - fpu_stmm4,
>> - fpu_stmm5,
>> - fpu_stmm6,
>> - fpu_stmm7,
>> - fpu_xmm0,
>> - fpu_xmm1,
>> - fpu_xmm2,
>> - fpu_xmm3,
>> - fpu_xmm4,
>> - fpu_xmm5,
>> - fpu_xmm6,
>> - fpu_xmm7,
>> - fpu_xmm8,
>> - fpu_xmm9,
>> - fpu_xmm10,
>> - fpu_xmm11,
>> - fpu_xmm12,
>> - fpu_xmm13,
>> - fpu_xmm14,
>> - fpu_xmm15
>> -};
>> -
>> -static const RegisterSet
>> -g_reg_sets[k_num_register_sets] =
>> -{
>> - { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
>> - { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }
>> -};
>> -
>> -// Computes the offset of the given GPR in the user data area.
>> -#define GPR_OFFSET(regname) \
>> - (offsetof(RegisterContextLinux_x86_64::UserArea, regs) + \
>> - offsetof(RegisterContextLinux_x86_64::GPR, regname))
>> -
>> -// Computes the offset of the given FPR in the user data area.
>> -#define FPR_OFFSET(regname) \
>> - (offsetof(RegisterContextLinux_x86_64::UserArea, i387) + \
>> - offsetof(RegisterContextLinux_x86_64::FPU, regname))
>> -
>> -// Number of bytes needed to represent a GPR.
>> -#define GPR_SIZE(reg) sizeof(((RegisterContextLinux_x86_64::GPR*)NULL)->reg)
>> -
>> -// Number of bytes needed to represent a FPR.
>> -#define FPR_SIZE(reg) sizeof(((RegisterContextLinux_x86_64::FPU*)NULL)->reg)
>> -
>> -// Number of bytes needed to represent the i'th FP register.
>> -#define FP_SIZE sizeof(((RegisterContextLinux_x86_64::MMSReg*)NULL)->bytes)
>> -
>> -// Number of bytes needed to represent an XMM register.
>> -#define XMM_SIZE sizeof(RegisterContextLinux_x86_64::XMMReg)
>> -
>> -#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
>> - { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
>> - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg } }
>> -
>> -#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \
>> - { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
>> - eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg } }
>> -
>> -#define DEFINE_FP(reg, i) \
>> - { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
>> - eFormatVectorOfUInt8, \
>> - { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \
>> - LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i } }
>> -
>> -#define DEFINE_XMM(reg, i) \
>> - { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
>> - eFormatVectorOfUInt8, \
>> - { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \
>> - LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i } }
>> -
>> -#define REG_CONTEXT_SIZE (sizeof(RegisterContextLinux_x86_64::GPR) + sizeof(RegisterContextLinux_x86_64::FPU))
>> -
>> -static RegisterInfo
>> -g_register_infos[k_num_registers] =
>> -{
>> - // General purpose registers.
>> - DEFINE_GPR(rax, NULL, gcc_dwarf_gpr_rax, gcc_dwarf_gpr_rax, LLDB_INVALID_REGNUM, gdb_gpr_rax),
>> - DEFINE_GPR(rbx, NULL, gcc_dwarf_gpr_rbx, gcc_dwarf_gpr_rbx, LLDB_INVALID_REGNUM, gdb_gpr_rbx),
>> - DEFINE_GPR(rcx, NULL, gcc_dwarf_gpr_rcx, gcc_dwarf_gpr_rcx, LLDB_INVALID_REGNUM, gdb_gpr_rcx),
>> - DEFINE_GPR(rdx, NULL, gcc_dwarf_gpr_rdx, gcc_dwarf_gpr_rdx, LLDB_INVALID_REGNUM, gdb_gpr_rdx),
>> - DEFINE_GPR(rdi, NULL, gcc_dwarf_gpr_rdi, gcc_dwarf_gpr_rdi, LLDB_INVALID_REGNUM, gdb_gpr_rdi),
>> - DEFINE_GPR(rsi, NULL, gcc_dwarf_gpr_rsi, gcc_dwarf_gpr_rsi, LLDB_INVALID_REGNUM, gdb_gpr_rsi),
>> - DEFINE_GPR(rbp, "fp", gcc_dwarf_gpr_rbp, gcc_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP, gdb_gpr_rbp),
>> - DEFINE_GPR(rsp, "sp", gcc_dwarf_gpr_rsp, gcc_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP, gdb_gpr_rsp),
>> - DEFINE_GPR(r8, NULL, gcc_dwarf_gpr_r8, gcc_dwarf_gpr_r8, LLDB_INVALID_REGNUM, gdb_gpr_r8),
>> - DEFINE_GPR(r9, NULL, gcc_dwarf_gpr_r9, gcc_dwarf_gpr_r9, LLDB_INVALID_REGNUM, gdb_gpr_r9),
>> - DEFINE_GPR(r10, NULL, gcc_dwarf_gpr_r10, gcc_dwarf_gpr_r10, LLDB_INVALID_REGNUM, gdb_gpr_r10),
>> - DEFINE_GPR(r11, NULL, gcc_dwarf_gpr_r11, gcc_dwarf_gpr_r11, LLDB_INVALID_REGNUM, gdb_gpr_r11),
>> - DEFINE_GPR(r12, NULL, gcc_dwarf_gpr_r12, gcc_dwarf_gpr_r12, LLDB_INVALID_REGNUM, gdb_gpr_r12),
>> - DEFINE_GPR(r13, NULL, gcc_dwarf_gpr_r13, gcc_dwarf_gpr_r13, LLDB_INVALID_REGNUM, gdb_gpr_r13),
>> - DEFINE_GPR(r14, NULL, gcc_dwarf_gpr_r14, gcc_dwarf_gpr_r14, LLDB_INVALID_REGNUM, gdb_gpr_r14),
>> - DEFINE_GPR(r15, NULL, gcc_dwarf_gpr_r15, gcc_dwarf_gpr_r15, LLDB_INVALID_REGNUM, gdb_gpr_r15),
>> - DEFINE_GPR(rip, "pc", gcc_dwarf_gpr_rip, gcc_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC, gdb_gpr_rip),
>> - DEFINE_GPR(rflags, "flags", LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_gpr_rflags),
>> - DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_cs),
>> - DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_fs),
>> - DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_gs),
>> - DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ss),
>> - DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ds),
>> - DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_es),
>> -
>> - // i387 Floating point registers.
>> - DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fcw),
>> - DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fsw),
>> - DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ftw),
>> - DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fop),
>> - DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ip),
>> - // FIXME: Extract segment from ip.
>> - DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs),
>> - DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_dp),
>> - // FIXME: Extract segment from dp.
>> - DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds),
>> - DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_mxcsr),
>> - DEFINE_FPR(mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
>> -
>> - // FP registers.
>> - DEFINE_FP(stmm, 0),
>> - DEFINE_FP(stmm, 1),
>> - DEFINE_FP(stmm, 2),
>> - DEFINE_FP(stmm, 3),
>> - DEFINE_FP(stmm, 4),
>> - DEFINE_FP(stmm, 5),
>> - DEFINE_FP(stmm, 6),
>> - DEFINE_FP(stmm, 7),
>> -
>> - // XMM registers
>> - DEFINE_XMM(xmm, 0),
>> - DEFINE_XMM(xmm, 1),
>> - DEFINE_XMM(xmm, 2),
>> - DEFINE_XMM(xmm, 3),
>> - DEFINE_XMM(xmm, 4),
>> - DEFINE_XMM(xmm, 5),
>> - DEFINE_XMM(xmm, 6),
>> - DEFINE_XMM(xmm, 7),
>> - DEFINE_XMM(xmm, 8),
>> - DEFINE_XMM(xmm, 9),
>> - DEFINE_XMM(xmm, 10),
>> - DEFINE_XMM(xmm, 11),
>> - DEFINE_XMM(xmm, 12),
>> - DEFINE_XMM(xmm, 13),
>> - DEFINE_XMM(xmm, 14),
>> - DEFINE_XMM(xmm, 15)
>> -};
>> -
>> -static unsigned GetRegOffset(unsigned reg)
>> -{
>> - assert(reg < k_num_registers && "Invalid register number.");
>> - return g_register_infos[reg].byte_offset;
>> -}
>> -
>> -#if 0 // These functions are currently not being used.
>> -static unsigned GetRegSize(unsigned reg)
>> -{
>> - assert(reg < k_num_registers && "Invalid register number.");
>> - return g_register_infos[reg].byte_size;
>> -}
>> -
>> -static bool IsGPR(unsigned reg)
>> -{
>> - return reg <= k_last_gpr; // GPR's come first.
>> -}
>> -
>> -static bool IsFPR(unsigned reg)
>> -{
>> - return (k_first_fpr <= reg && reg <= k_last_fpr);
>> -}
>> -#endif
>> -
>> -RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(Thread &thread,
>> - uint32_t concrete_frame_idx)
>> - : RegisterContextLinux(thread, concrete_frame_idx)
>> -{
>> -}
>> -
>> -RegisterContextLinux_x86_64::~RegisterContextLinux_x86_64()
>> -{
>> -}
>> -
>> -ProcessMonitor &
>> -RegisterContextLinux_x86_64::GetMonitor()
>> -{
>> - ProcessLinux *process = static_cast<ProcessLinux*>(CalculateProcess());
>> - return process->GetMonitor();
>> -}
>> -
>> -void
>> -RegisterContextLinux_x86_64::Invalidate()
>> -{
>> -}
>> -
>> -void
>> -RegisterContextLinux_x86_64::InvalidateAllRegisters()
>> -{
>> -}
>> -
>> -size_t
>> -RegisterContextLinux_x86_64::GetRegisterCount()
>> -{
>> - return k_num_registers;
>> -}
>> -
>> -const RegisterInfo *
>> -RegisterContextLinux_x86_64::GetRegisterInfoAtIndex(uint32_t reg)
>> -{
>> - if (reg < k_num_registers)
>> - return &g_register_infos[reg];
>> - else
>> - return NULL;
>> -}
>> -
>> -size_t
>> -RegisterContextLinux_x86_64::GetRegisterSetCount()
>> -{
>> - return k_num_register_sets;
>> -}
>> -
>> -const RegisterSet *
>> -RegisterContextLinux_x86_64::GetRegisterSet(uint32_t set)
>> -{
>> - if (set < k_num_register_sets)
>> - return &g_reg_sets[set];
>> - else
>> - return NULL;
>> -}
>> -
>> -unsigned
>> -RegisterContextLinux_x86_64::GetRegisterIndexFromOffset(unsigned offset)
>> -{
>> - unsigned reg;
>> - for (reg = 0; reg < k_num_registers; reg++)
>> - {
>> - if (g_register_infos[reg].byte_offset == offset)
>> - break;
>> - }
>> - assert(reg < k_num_registers && "Invalid register offset.");
>> - return reg;
>> -}
>> -
>> -const char *
>> -RegisterContextLinux_x86_64::GetRegisterName(unsigned reg)
>> -{
>> - assert(reg < k_num_registers && "Invalid register offset.");
>> - return g_register_infos[reg].name;
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
>> - RegisterValue &value)
>> -{
>> - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
>> - ProcessMonitor &monitor = GetMonitor();
>> - return monitor.ReadRegisterValue(GetRegOffset(reg), value);
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp)
>> -{
>> - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
>> - if (data_sp && ReadGPR () && ReadFPR ())
>> - {
>> - uint8_t *dst = data_sp->GetBytes();
>> - ::memcpy (dst, &user.regs, sizeof(user.regs));
>> - dst += sizeof(user.regs);
>> -
>> - ::memcpy (dst, &user.i387, sizeof(user.i387));
>> - return true;
>> - }
>> - return false;
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg_info,
>> - const lldb_private::RegisterValue &value)
>> -{
>> - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
>> - ProcessMonitor &monitor = GetMonitor();
>> - return monitor.WriteRegisterValue(GetRegOffset(reg), value);
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp)
>> -{
>> - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
>> - {
>> - const uint8_t *src = data_sp->GetBytes();
>> - ::memcpy (&user.regs, src, sizeof(user.regs));
>> - src += sizeof(user.regs);
>> -
>> - ::memcpy (&user.i387, src, sizeof(user.i387));
>> - return WriteGPR() & WriteFPR();
>> - }
>> - return false;
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::UpdateAfterBreakpoint()
>> -{
>> - // PC points one byte past the int3 responsible for the breakpoint.
>> - lldb::addr_t pc;
>> -
>> - if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
>> - return false;
>> -
>> - SetPC(pc - 1);
>> - return true;
>> -}
>> -
>> -uint32_t
>> -RegisterContextLinux_x86_64::ConvertRegisterKindToRegisterNumber(uint32_t kind,
>> - uint32_t num)
>> -{
>> - if (kind == eRegisterKindGeneric)
>> - {
>> - switch (num)
>> - {
>> - case LLDB_REGNUM_GENERIC_PC: return gpr_rip;
>> - case LLDB_REGNUM_GENERIC_SP: return gpr_rsp;
>> - case LLDB_REGNUM_GENERIC_FP: return gpr_rbp;
>> - case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
>> - case LLDB_REGNUM_GENERIC_RA:
>> - default:
>> - return LLDB_INVALID_REGNUM;
>> - }
>> - }
>> -
>> - if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
>> - {
>> - switch (num)
>> - {
>> - case gcc_dwarf_gpr_rax: return gpr_rax;
>> - case gcc_dwarf_gpr_rdx: return gpr_rdx;
>> - case gcc_dwarf_gpr_rcx: return gpr_rcx;
>> - case gcc_dwarf_gpr_rbx: return gpr_rbx;
>> - case gcc_dwarf_gpr_rsi: return gpr_rsi;
>> - case gcc_dwarf_gpr_rdi: return gpr_rdi;
>> - case gcc_dwarf_gpr_rbp: return gpr_rbp;
>> - case gcc_dwarf_gpr_rsp: return gpr_rsp;
>> - case gcc_dwarf_gpr_r8: return gpr_r8;
>> - case gcc_dwarf_gpr_r9: return gpr_r9;
>> - case gcc_dwarf_gpr_r10: return gpr_r10;
>> - case gcc_dwarf_gpr_r11: return gpr_r11;
>> - case gcc_dwarf_gpr_r12: return gpr_r12;
>> - case gcc_dwarf_gpr_r13: return gpr_r13;
>> - case gcc_dwarf_gpr_r14: return gpr_r14;
>> - case gcc_dwarf_gpr_r15: return gpr_r15;
>> - case gcc_dwarf_gpr_rip: return gpr_rip;
>> - case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
>> - case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
>> - case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
>> - case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
>> - case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
>> - case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
>> - case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
>> - case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
>> - case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
>> - case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
>> - case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
>> - case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
>> - case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
>> - case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
>> - case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
>> - case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
>> - case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
>> - case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
>> - case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
>> - case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
>> - case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
>> - case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
>> - case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
>> - case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
>> - default:
>> - return LLDB_INVALID_REGNUM;
>> - }
>> - }
>> -
>> - if (kind == eRegisterKindGDB)
>> - {
>> - switch (num)
>> - {
>> - case gdb_gpr_rax : return gpr_rax;
>> - case gdb_gpr_rbx : return gpr_rbx;
>> - case gdb_gpr_rcx : return gpr_rcx;
>> - case gdb_gpr_rdx : return gpr_rdx;
>> - case gdb_gpr_rsi : return gpr_rsi;
>> - case gdb_gpr_rdi : return gpr_rdi;
>> - case gdb_gpr_rbp : return gpr_rbp;
>> - case gdb_gpr_rsp : return gpr_rsp;
>> - case gdb_gpr_r8 : return gpr_r8;
>> - case gdb_gpr_r9 : return gpr_r9;
>> - case gdb_gpr_r10 : return gpr_r10;
>> - case gdb_gpr_r11 : return gpr_r11;
>> - case gdb_gpr_r12 : return gpr_r12;
>> - case gdb_gpr_r13 : return gpr_r13;
>> - case gdb_gpr_r14 : return gpr_r14;
>> - case gdb_gpr_r15 : return gpr_r15;
>> - case gdb_gpr_rip : return gpr_rip;
>> - case gdb_gpr_rflags : return gpr_rflags;
>> - case gdb_gpr_cs : return gpr_cs;
>> - case gdb_gpr_ss : return gpr_ss;
>> - case gdb_gpr_ds : return gpr_ds;
>> - case gdb_gpr_es : return gpr_es;
>> - case gdb_gpr_fs : return gpr_fs;
>> - case gdb_gpr_gs : return gpr_gs;
>> - case gdb_fpu_stmm0 : return fpu_stmm0;
>> - case gdb_fpu_stmm1 : return fpu_stmm1;
>> - case gdb_fpu_stmm2 : return fpu_stmm2;
>> - case gdb_fpu_stmm3 : return fpu_stmm3;
>> - case gdb_fpu_stmm4 : return fpu_stmm4;
>> - case gdb_fpu_stmm5 : return fpu_stmm5;
>> - case gdb_fpu_stmm6 : return fpu_stmm6;
>> - case gdb_fpu_stmm7 : return fpu_stmm7;
>> - case gdb_fpu_fcw : return fpu_fcw;
>> - case gdb_fpu_fsw : return fpu_fsw;
>> - case gdb_fpu_ftw : return fpu_ftw;
>> - case gdb_fpu_cs : return fpu_cs;
>> - case gdb_fpu_ip : return fpu_ip;
>> - case gdb_fpu_ds : return fpu_ds;
>> - case gdb_fpu_dp : return fpu_dp;
>> - case gdb_fpu_fop : return fpu_fop;
>> - case gdb_fpu_xmm0 : return fpu_xmm0;
>> - case gdb_fpu_xmm1 : return fpu_xmm1;
>> - case gdb_fpu_xmm2 : return fpu_xmm2;
>> - case gdb_fpu_xmm3 : return fpu_xmm3;
>> - case gdb_fpu_xmm4 : return fpu_xmm4;
>> - case gdb_fpu_xmm5 : return fpu_xmm5;
>> - case gdb_fpu_xmm6 : return fpu_xmm6;
>> - case gdb_fpu_xmm7 : return fpu_xmm7;
>> - case gdb_fpu_xmm8 : return fpu_xmm8;
>> - case gdb_fpu_xmm9 : return fpu_xmm9;
>> - case gdb_fpu_xmm10 : return fpu_xmm10;
>> - case gdb_fpu_xmm11 : return fpu_xmm11;
>> - case gdb_fpu_xmm12 : return fpu_xmm12;
>> - case gdb_fpu_xmm13 : return fpu_xmm13;
>> - case gdb_fpu_xmm14 : return fpu_xmm14;
>> - case gdb_fpu_xmm15 : return fpu_xmm15;
>> - case gdb_fpu_mxcsr : return fpu_mxcsr;
>> - default:
>> - return LLDB_INVALID_REGNUM;
>> - }
>> - }
>> - else if (kind == eRegisterKindLLDB)
>> - {
>> - return num;
>> - }
>> -
>> - return LLDB_INVALID_REGNUM;
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::HardwareSingleStep(bool enable)
>> -{
>> - enum { TRACE_BIT = 0x100 };
>> - uint64_t rflags;
>> -
>> - if ((rflags = ReadRegisterAsUnsigned(gpr_rflags, -1UL)) == -1UL)
>> - return false;
>> -
>> - if (enable)
>> - {
>> - if (rflags & TRACE_BIT)
>> - return true;
>> -
>> - rflags |= TRACE_BIT;
>> - }
>> - else
>> - {
>> - if (!(rflags & TRACE_BIT))
>> - return false;
>> -
>> - rflags &= ~TRACE_BIT;
>> - }
>> -
>> - return WriteRegisterFromUnsigned(gpr_rflags, rflags);
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::ReadGPR()
>> -{
>> - ProcessMonitor &monitor = GetMonitor();
>> - return monitor.ReadGPR(&user.regs);
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::ReadFPR()
>> -{
>> - ProcessMonitor &monitor = GetMonitor();
>> - return monitor.ReadFPR(&user.i387);
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::WriteGPR()
>> -{
>> - ProcessMonitor &monitor = GetMonitor();
>> - return monitor.WriteGPR(&user.regs);
>> -}
>> -
>> -bool
>> -RegisterContextLinux_x86_64::WriteFPR()
>> -{
>> - ProcessMonitor &monitor = GetMonitor();
>> - return monitor.WriteFPR(&user.i387);
>> -}
>> Index: source/Plugins/Process/Linux/ProcessMessage.h
>> ===================================================================
>> --- source/Plugins/Process/Linux/ProcessMessage.h (revision 147560)
>> +++ source/Plugins/Process/Linux/ProcessMessage.h (working copy)
>> @@ -1,171 +0,0 @@
>> -//===-- ProcessMessage.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_ProcessMessage_H_
>> -#define liblldb_ProcessMessage_H_
>> -
>> -#include <cassert>
>> -
>> -#include "lldb/lldb-defines.h"
>> -#include "lldb/lldb-types.h"
>> -
>> -class ProcessMessage
>> -{
>> -public:
>> -
>> - /// The type of signal this message can correspond to.
>> - enum Kind
>> - {
>> - eInvalidMessage,
>> - eExitMessage,
>> - eLimboMessage,
>> - eSignalMessage,
>> - eSignalDeliveredMessage,
>> - eTraceMessage,
>> - eBreakpointMessage,
>> - eCrashMessage
>> - };
>> -
>> - enum CrashReason
>> - {
>> - eInvalidCrashReason,
>> -
>> - // SIGSEGV crash reasons.
>> - eInvalidAddress,
>> - ePrivilegedAddress,
>> -
>> - // SIGILL crash reasons.
>> - eIllegalOpcode,
>> - eIllegalOperand,
>> - eIllegalAddressingMode,
>> - eIllegalTrap,
>> - ePrivilegedOpcode,
>> - ePrivilegedRegister,
>> - eCoprocessorError,
>> - eInternalStackError,
>> -
>> - // SIGBUS crash reasons,
>> - eIllegalAlignment,
>> - eIllegalAddress,
>> - eHardwareError,
>> -
>> - // SIGFPE crash reasons,
>> - eIntegerDivideByZero,
>> - eIntegerOverflow,
>> - eFloatDivideByZero,
>> - eFloatOverflow,
>> - eFloatUnderflow,
>> - eFloatInexactResult,
>> - eFloatInvalidOperation,
>> - eFloatSubscriptRange
>> - };
>> -
>> - ProcessMessage()
>> - : m_tid(LLDB_INVALID_PROCESS_ID),
>> - m_kind(eInvalidMessage),
>> - m_crash_reason(eInvalidCrashReason),
>> - m_status(0),
>> - m_addr(0) { }
>> -
>> - Kind GetKind() const { return m_kind; }
>> -
>> - lldb::tid_t GetTID() const { return m_tid; }
>> -
>> - /// Indicates that the thread @p tid is about to exit with status @p status.
>> - static ProcessMessage Limbo(lldb::tid_t tid, int status) {
>> - return ProcessMessage(tid, eLimboMessage, status);
>> - }
>> -
>> - /// Indicates that the thread @p tid had the signal @p signum delivered.
>> - static ProcessMessage Signal(lldb::tid_t tid, int signum) {
>> - return ProcessMessage(tid, eSignalMessage, signum);
>> - }
>> -
>> - /// Indicates that a signal @p signum generated by the debugging process was
>> - /// delivered to the thread @p tid.
>> - static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
>> - return ProcessMessage(tid, eSignalDeliveredMessage, signum);
>> - }
>> -
>> - /// Indicates that the thread @p tid encountered a trace point.
>> - static ProcessMessage Trace(lldb::tid_t tid) {
>> - return ProcessMessage(tid, eTraceMessage);
>> - }
>> -
>> - /// Indicates that the thread @p tid encountered a break point.
>> - static ProcessMessage Break(lldb::tid_t tid) {
>> - return ProcessMessage(tid, eBreakpointMessage);
>> - }
>> -
>> - /// Indicates that the thread @p tid crashed.
>> - static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason,
>> - int signo, lldb::addr_t fault_addr) {
>> - ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
>> - message.m_crash_reason = reason;
>> - return message;
>> - }
>> -
>> - int GetExitStatus() const {
>> - assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
>> - return m_status;
>> - }
>> -
>> - int GetSignal() const {
>> - assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
>> - GetKind() == eSignalDeliveredMessage);
>> - return m_status;
>> - }
>> -
>> - int GetStopStatus() const {
>> - assert(GetKind() == eSignalMessage);
>> - return m_status;
>> - }
>> -
>> - CrashReason GetCrashReason() const {
>> - assert(GetKind() == eCrashMessage);
>> - return m_crash_reason;
>> - }
>> -
>> - lldb::addr_t GetFaultAddress() const {
>> - assert(GetKind() == eCrashMessage);
>> - return m_addr;
>> - }
>> -
>> - static const char *
>> - GetCrashReasonString(CrashReason reason);
>> -
>> - const char *
>> - PrintCrashReason() const;
>> -
>> - static const char *
>> - PrintCrashReason(CrashReason reason);
>> -
>> - const char *
>> - PrintKind() const;
>> -
>> - static const char *
>> - PrintKind(Kind);
>> -
>> -private:
>> - ProcessMessage(lldb::tid_t tid, Kind kind,
>> - int status = 0, lldb::addr_t addr = 0)
>> - : m_tid(tid),
>> - m_kind(kind),
>> - m_crash_reason(eInvalidCrashReason),
>> - m_status(status),
>> - m_addr(addr) { }
>> -
>> - lldb::tid_t m_tid;
>> - Kind m_kind : 8;
>> - CrashReason m_crash_reason : 8;
>> - int m_status;
>> - lldb::addr_t m_addr;
>> -};
>> -
>> -#endif // #ifndef liblldb_ProcessMessage_H_
>> Index: source/Plugins/Process/Linux/ProcessMonitor.h
>> ===================================================================
>> --- source/Plugins/Process/Linux/ProcessMonitor.h (revision 147560)
>> +++ 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/Makefile
>> ===================================================================
>> --- source/Plugins/Process/Linux/Makefile (revision 147560)
>> +++ 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/LinuxThread.h
>> ===================================================================
>> --- source/Plugins/Process/Linux/LinuxThread.h (revision 147560)
>> +++ source/Plugins/Process/Linux/LinuxThread.h (working copy)
>> @@ -1,102 +0,0 @@
>> -//===-- LinuxThread.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_LinuxThread_H_
>> -#define liblldb_LinuxThread_H_
>> -
>> -// C Includes
>> -// C++ Includes
>> -#include <memory>
>> -
>> -// Other libraries and framework includes
>> -#include "lldb/Target/Thread.h"
>> -
>> -class ProcessMessage;
>> -class ProcessMonitor;
>> -class RegisterContextLinux;
>> -
>> -//------------------------------------------------------------------------------
>> -// @class LinuxThread
>> -// @brief Abstraction of a linux process (thread).
>> -class LinuxThread
>> - : public lldb_private::Thread
>> -{
>> -public:
>> - LinuxThread(lldb_private::Process &process, lldb::tid_t tid);
>> -
>> - virtual ~LinuxThread();
>> -
>> - void
>> - RefreshStateAfterStop();
>> -
>> - bool
>> - WillResume(lldb::StateType resume_state);
>> -
>> - const char *
>> - GetInfo();
>> -
>> - virtual lldb::RegisterContextSP
>> - GetRegisterContext();
>> -
>> - virtual lldb::RegisterContextSP
>> - CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
>> -
>> - //--------------------------------------------------------------------------
>> - // These static functions provide a mapping from the register offset
>> - // back to the register index or name for use in debugging or log
>> - // output.
>> -
>> - static unsigned
>> - GetRegisterIndexFromOffset(unsigned offset);
>> -
>> - static const char *
>> - GetRegisterName(unsigned reg);
>> -
>> - static const char *
>> - GetRegisterNameFromOffset(unsigned offset);
>> -
>> - //--------------------------------------------------------------------------
>> - // These methods form a specialized interface to linux threads.
>> - //
>> - bool Resume();
>> -
>> - void Notify(const ProcessMessage &message);
>> -
>> -private:
>> - RegisterContextLinux *
>> - GetRegisterContextLinux ()
>> - {
>> - if (!m_reg_context_sp)
>> - GetRegisterContext();
>> - return (RegisterContextLinux *)m_reg_context_sp.get();
>> - }
>> -
>> - std::auto_ptr<lldb_private::StackFrame> m_frame_ap;
>> -
>> - lldb::BreakpointSiteSP m_breakpoint;
>> - lldb::StopInfoSP m_stop_info;
>> -
>> - ProcessMonitor &
>> - GetMonitor();
>> -
>> - lldb::StopInfoSP
>> - GetPrivateStopReason();
>> -
>> - void BreakNotify(const ProcessMessage &message);
>> - void TraceNotify(const ProcessMessage &message);
>> - void LimboNotify(const ProcessMessage &message);
>> - void SignalNotify(const ProcessMessage &message);
>> - void SignalDeliveredNotify(const ProcessMessage &message);
>> - void CrashNotify(const ProcessMessage &message);
>> -
>> - lldb_private::Unwind *
>> - GetUnwinder();
>> -};
>> -
>> -#endif // #ifndef liblldb_LinuxThread_H_
>> Index: source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h
>> ===================================================================
>> --- source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h (revision 147560)
>> +++ 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/Plugins/Process/POSIX/POSIXThread.h
>> ===================================================================
>> --- source/Plugins/Process/POSIX/POSIXThread.h (revision 0)
>> +++ source/Plugins/Process/POSIX/POSIXThread.h (revision 0)
>> @@ -0,0 +1,106 @@
>> +//===-- POSIXThread.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_POSIXThread_H_
>> +#define liblldb_POSIXThread_H_
>> +
>> +// C Includes
>> +// C++ Includes
>> +#include <memory>
>> +
>> +// Other libraries and framework includes
>> +#include "lldb/Target/Thread.h"
>> +#include "RegisterContextPOSIX.h"
>> +
>> +class ProcessMessage;
>> +class ProcessMonitor;
>> +class RegisterContextPOSIX;
>> +
>> +//------------------------------------------------------------------------------
>> +// @class POSIXThread
>> +// @brief Abstraction of a linux process (thread).
>> +class POSIXThread
>> + : public lldb_private::Thread
>> +{
>> +public:
>> + POSIXThread(lldb_private::Process &process, lldb::tid_t tid);
>> +
>> + virtual ~POSIXThread();
>> +
>> + void
>> + RefreshStateAfterStop();
>> +
>> + bool
>> + WillResume(lldb::StateType resume_state);
>> +
>> + const char *
>> + GetInfo();
>> +
>> + virtual lldb::RegisterContextSP
>> + GetRegisterContext();
>> +
>> + virtual lldb::RegisterContextSP
>> + CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
>> +
>> + //--------------------------------------------------------------------------
>> + // These static functions provide a mapping from the register offset
>> + // back to the register index or name for use in debugging or log
>> + // output.
>> +
>> + static unsigned
>> + GetRegisterIndexFromOffset(unsigned offset);
>> +
>> + static const char *
>> + GetRegisterName(unsigned reg);
>> +
>> + static const char *
>> + GetRegisterNameFromOffset(unsigned offset);
>> +
>> + //--------------------------------------------------------------------------
>> + // These methods form a specialized interface to linux threads.
>> + //
>> + bool Resume();
>> +
>> + void Notify(const ProcessMessage &message);
>> +
>> +private:
>> + RegisterContextPOSIX *
>> + GetRegisterContextPOSIX ()
>> + {
>> + if (!m_reg_context_sp)
>> + m_reg_context_sp = GetRegisterContext();
>> +#if 0
>> + return dynamic_cast<RegisterContextPOSIX*>(m_reg_context_sp.get());
>> +#endif
>> + return (RegisterContextPOSIX *)m_reg_context_sp.get();
>> + }
>> +
>> + std::auto_ptr<lldb_private::StackFrame> m_frame_ap;
>> +
>> + lldb::BreakpointSiteSP m_breakpoint;
>> + lldb::StopInfoSP m_stop_info;
>> +
>> + ProcessMonitor &
>> + GetMonitor();
>> +
>> + lldb::StopInfoSP
>> + GetPrivateStopReason();
>> +
>> + void BreakNotify(const ProcessMessage &message);
>> + void TraceNotify(const ProcessMessage &message);
>> + void LimboNotify(const ProcessMessage &message);
>> + void SignalNotify(const ProcessMessage &message);
>> + void SignalDeliveredNotify(const ProcessMessage &message);
>> + void CrashNotify(const ProcessMessage &message);
>> +
>> + lldb_private::Unwind *
>> + GetUnwinder();
>> +};
>> +
>> +#endif // #ifndef liblldb_POSIXThread_H_
>> Index: source/Plugins/Process/POSIX/ProcessPOSIX.cpp
>> ===================================================================
>> --- source/Plugins/Process/POSIX/ProcessPOSIX.cpp (revision 0)
>> +++ source/Plugins/Process/POSIX/ProcessPOSIX.cpp (revision 0)
>> @@ -0,0 +1,594 @@
>> +//===-- ProcessPOSIX.cpp ----------------------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +// C Includes
>> +#include <errno.h>
>> +
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +#include "lldb/Core/PluginManager.h"
>> +#include "lldb/Core/State.h"
>> +#include "lldb/Host/Host.h"
>> +#include "lldb/Symbol/ObjectFile.h"
>> +#include "lldb/Target/DynamicLoader.h"
>> +#include "lldb/Target/Target.h"
>> +
>> +#include "ProcessPOSIX.h"
>> +#include "ProcessPOSIXLog.h"
>> +#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
>> +#include "ProcessMonitor.h"
>> +#include "POSIXThread.h"
>> +
>> +using namespace lldb;
>> +using namespace lldb_private;
>> +
>> +//------------------------------------------------------------------------------
>> +// Static functions.
>> +#if 0
>> +Process*
>> +ProcessPOSIX::CreateInstance(Target& target, Listener &listener)
>> +{
>> + return new ProcessPOSIX(target, listener);
>> +}
>> +
>> +
>> +void
>> +ProcessPOSIX::Initialize()
>> +{
>> + static bool g_initialized = false;
>> +
>> + if (!g_initialized)
>> + {
>> + g_initialized = true;
>> + PluginManager::RegisterPlugin(GetPluginNameStatic(),
>> + GetPluginDescriptionStatic(),
>> + CreateInstance);
>> +
>> + Log::Callbacks log_callbacks = {
>> + ProcessPOSIXLog::DisableLog,
>> + ProcessPOSIXLog::EnableLog,
>> + ProcessPOSIXLog::ListLogCategories
>> + };
>> +
>> + Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks);
>> + }
>> +}
>> +#endif
>> +
>> +//------------------------------------------------------------------------------
>> +// Constructors and destructors.
>> +
>> +ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener)
>> + : Process(target, listener),
>> + m_monitor(NULL),
>> + m_module(NULL),
>> + m_in_limbo(false),
>> + m_exit_now(false)
>> +{
>> + // FIXME: Putting this code in the ctor and saving the byte order in a
>> + // member variable is a hack to avoid const qual issues in GetByteOrder.
>> + ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
>> + m_byte_order = obj_file->GetByteOrder();
>> +}
>> +
>> +ProcessPOSIX::~ProcessPOSIX()
>> +{
>> + delete m_monitor;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +// Process protocol.
>> +
>> +bool
>> +ProcessPOSIX::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
>> +ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid)
>> +{
>> + Error error;
>> + assert(m_monitor == NULL);
>> +
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
>> + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
>> + log->Printf ("ProcessPOSIX::%s(pid = %i)", __FUNCTION__, GetID());
>> +
>> + m_monitor = new ProcessMonitor(this, pid, error);
>> +
>> + if (!error.Success())
>> + return error;
>> +
>> + SetID(pid);
>> + return error;
>> +}
>> +
>> +Error
>> +ProcessPOSIX::WillLaunch(Module* module)
>> +{
>> + Error error;
>> + return error;
>> +}
>> +
>> +const char *
>> +ProcessPOSIX::GetFilePath(
>> + const lldb_private::ProcessLaunchInfo::FileAction *file_action,
>> + const char *default_path)
>> +{
>> + const char *pts_name = "/dev/pts/";
>> + const char *path = NULL;
>> +
>> + if (file_action)
>> + {
>> + if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
>> + path = file_action->GetPath();
>> + // By default the stdio paths passed in will be pseudo-terminal
>> + // (/dev/pts). If so, convert to using a different default path
>> + // instead to redirect I/O to the debugger console. This should
>> + // also handle user overrides to /dev/null or a different file.
>> + if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0)
>> + path = default_path;
>> + }
>> +
>> + return path;
>> +}
>> +
>> +Error
>> +ProcessPOSIX::DoLaunch (Module *module,
>> + const ProcessLaunchInfo &launch_info)
>> +{
>> + Error error;
>> + assert(m_monitor == NULL);
>> +
>> + SetPrivateState(eStateLaunching);
>> +
>> + const lldb_private::ProcessLaunchInfo::FileAction *file_action;
>> +
>> + // Default of NULL will mean to use existing open file descriptors
>> + const char *stdin_path = NULL;
>> + const char *stdout_path = NULL;
>> + const char *stderr_path = NULL;
>> +
>> + file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
>> + stdin_path = GetFilePath(file_action, stdin_path);
>> +
>> + file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
>> + stdout_path = GetFilePath(file_action, stdout_path);
>> +
>> + file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
>> + stderr_path = GetFilePath(file_action, stderr_path);
>> +
>> + 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
>> +ProcessPOSIX::DidLaunch()
>> +{
>> +}
>> +
>> +Error
>> +ProcessPOSIX::DoResume()
>> +{
>> + 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)
>> + {
>> + POSIXThread *thread = static_cast<POSIXThread*>(
>> + m_thread_list.GetThreadAtIndex(i, false).get());
>> + did_resume = thread->Resume() || did_resume;
>> + }
>> + assert(did_resume && "Process resume failed!");
>> +
>> + return Error();
>> +}
>> +
>> +addr_t
>> +ProcessPOSIX::GetImageInfoAddress()
>> +{
>> + 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;
>> +}
>> +
>> +Error
>> +ProcessPOSIX::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
>> +ProcessPOSIX::DoDetach()
>> +{
>> + Error error;
>> +
>> + error = m_monitor->Detach();
>> + if (error.Success())
>> + SetPrivateState(eStateDetached);
>> +
>> + return error;
>> +}
>> +
>> +Error
>> +ProcessPOSIX::DoSignal(int signal)
>> +{
>> + Error error;
>> +
>> + if (kill(GetID(), signal))
>> + error.SetErrorToErrno();
>> +
>> + return error;
>> +}
>> +
>> +Error
>> +ProcessPOSIX::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
>> +ProcessPOSIX::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
>> +ProcessPOSIX::RefreshStateAfterStop()
>> +{
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
>> + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
>> + log->Printf ("ProcessPOSIX::%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 ("ProcessPOSIX::%s() pid = %i", __FUNCTION__, tid);
>> + POSIXThread *thread = static_cast<POSIXThread*>(
>> + GetThreadList().FindThreadByID(tid, false).get());
>> +
>> + assert(thread);
>> + thread->Notify(message);
>> +
>> + m_message_queue.pop();
>> +}
>> +
>> +bool
>> +ProcessPOSIX::IsAlive()
>> +{
>> + StateType state = GetPrivateState();
>> + return state != eStateDetached && state != eStateExited && state != eStateInvalid;
>> +}
>> +
>> +size_t
>> +ProcessPOSIX::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
>> +ProcessPOSIX::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
>> +ProcessPOSIX::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
>> +ProcessPOSIX::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
>> +ProcessPOSIX::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
>> +ProcessPOSIX::EnableBreakpoint(BreakpointSite *bp_site)
>> +{
>> + return EnableSoftwareBreakpoint(bp_site);
>> +}
>> +
>> +Error
>> +ProcessPOSIX::DisableBreakpoint(BreakpointSite *bp_site)
>> +{
>> + return DisableSoftwareBreakpoint(bp_site);
>> +}
>> +
>> +uint32_t
>> +ProcessPOSIX::UpdateThreadListIfNeeded()
>> +{
>> + // Do not allow recursive updates.
>> + return m_thread_list.GetSize(false);
>> +}
>> +
>> +uint32_t
>> +ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
>> +{
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
>> + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
>> + log->Printf ("ProcessPOSIX::%s() (pid = %i)", __FUNCTION__, GetID());
>> +
>> + // Update the process thread list with this new thread.
>> + // FIXME: We should be using tid, not pid.
>> + assert(m_monitor);
>> + ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
>> + if (!thread_sp)
>> + thread_sp.reset(new POSIXThread(*this, GetID()));
>> +
>> + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
>> + log->Printf ("ProcessPOSIX::%s() updated pid = %i", __FUNCTION__, GetID());
>> + new_thread_list.AddThread(thread_sp);
>> +
>> + return new_thread_list.GetSize(false);
>> +}
>> +
>> +ByteOrder
>> +ProcessPOSIX::GetByteOrder() const
>> +{
>> + // FIXME: We should be able to extract this value directly. See comment in
>> + // ProcessPOSIX().
>> + return m_byte_order;
>> +}
>> +
>> +size_t
>> +ProcessPOSIX::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
>> +ProcessPOSIX::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
>> +ProcessPOSIX::GetSTDERR(char *buf, size_t len, Error &error)
>> +{
>> + return GetSTDOUT(buf, len, error);
>> +}
>> +
>> +UnixSignals &
>> +ProcessPOSIX::GetUnixSignals()
>> +{
>> + return m_signals;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +// Utility functions.
>> +
>> +bool
>> +ProcessPOSIX::HasExited()
>> +{
>> + switch (GetPrivateState())
>> + {
>> + default:
>> + break;
>> +
>> + case eStateDetached:
>> + case eStateExited:
>> + return true;
>> + }
>> +
>> + return false;
>> +}
>> +
>> +bool
>> +ProcessPOSIX::IsStopped()
>> +{
>> + switch (GetPrivateState())
>> + {
>> + default:
>> + break;
>> +
>> + case eStateStopped:
>> + case eStateCrashed:
>> + case eStateSuspended:
>> + return true;
>> + }
>> +
>> + return false;
>> +}
>> Index: source/Plugins/Process/POSIX/RegisterContext_i386.cpp
>> ===================================================================
>> --- source/Plugins/Process/POSIX/RegisterContext_i386.cpp (revision 0)
>> +++ source/Plugins/Process/POSIX/RegisterContext_i386.cpp (revision 0)
>> @@ -0,0 +1,643 @@
>> +//===-- RegisterContextPOSIX_i386.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/Core/DataExtractor.h"
>> +#include "lldb/Target/Thread.h"
>> +#include "lldb/Host/Endian.h"
>> +
>> +#include "ProcessPOSIX.h"
>> +#include "ProcessPOSIXLog.h"
>> +#include "ProcessMonitor.h"
>> +#include "RegisterContext_i386.h"
>> +
>> +using namespace lldb_private;
>> +using namespace lldb;
>> +
>> +enum
>> +{
>> + k_first_gpr,
>> + gpr_eax = k_first_gpr,
>> + gpr_ebx,
>> + gpr_ecx,
>> + gpr_edx,
>> + gpr_edi,
>> + gpr_esi,
>> + gpr_ebp,
>> + gpr_esp,
>> + gpr_ss,
>> + gpr_eflags,
>> +#ifdef __FreeBSD__
>> + gpr_orig_ax,
>> +#endif
>> + gpr_eip,
>> + gpr_cs,
>> + gpr_ds,
>> + gpr_es,
>> + gpr_fs,
>> + gpr_gs,
>> + k_last_gpr = gpr_gs,
>> +
>> + k_first_fpr,
>> + fpu_fcw = k_first_fpr,
>> + fpu_fsw,
>> + fpu_ftw,
>> + fpu_fop,
>> + fpu_ip,
>> + fpu_cs,
>> + fpu_foo,
>> + fpu_fos,
>> + fpu_mxcsr,
>> + fpu_stmm0,
>> + fpu_stmm1,
>> + fpu_stmm2,
>> + fpu_stmm3,
>> + fpu_stmm4,
>> + fpu_stmm5,
>> + fpu_stmm6,
>> + fpu_stmm7,
>> + fpu_xmm0,
>> + fpu_xmm1,
>> + fpu_xmm2,
>> + fpu_xmm3,
>> + fpu_xmm4,
>> + fpu_xmm5,
>> + fpu_xmm6,
>> + fpu_xmm7,
>> + k_last_fpr = fpu_xmm7,
>> +
>> + k_num_registers,
>> + k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
>> + k_num_fpu_registers = k_last_fpr - k_first_fpr + 1
>> +};
>> +
>> +// Number of register sets provided by this context.
>> +enum
>> +{
>> + k_num_register_sets = 2
>> +};
>> +
>> +enum
>> +{
>> + gcc_eax = 0,
>> + gcc_ecx,
>> + gcc_edx,
>> + gcc_ebx,
>> + gcc_ebp,
>> + gcc_esp,
>> + gcc_esi,
>> + gcc_edi,
>> + gcc_eip,
>> + gcc_eflags
>> +};
>> +
>> +enum
>> +{
>> + dwarf_eax = 0,
>> + dwarf_ecx,
>> + dwarf_edx,
>> + dwarf_ebx,
>> + dwarf_esp,
>> + dwarf_ebp,
>> + dwarf_esi,
>> + dwarf_edi,
>> + dwarf_eip,
>> + dwarf_eflags,
>> + dwarf_stmm0 = 11,
>> + dwarf_stmm1,
>> + dwarf_stmm2,
>> + dwarf_stmm3,
>> + dwarf_stmm4,
>> + dwarf_stmm5,
>> + dwarf_stmm6,
>> + dwarf_stmm7,
>> + dwarf_xmm0 = 21,
>> + dwarf_xmm1,
>> + dwarf_xmm2,
>> + dwarf_xmm3,
>> + dwarf_xmm4,
>> + dwarf_xmm5,
>> + dwarf_xmm6,
>> + dwarf_xmm7
>> +};
>> +
>> +enum
>> +{
>> + gdb_eax = 0,
>> + gdb_ecx = 1,
>> + gdb_edx = 2,
>> + gdb_ebx = 3,
>> + gdb_esp = 4,
>> + gdb_ebp = 5,
>> + gdb_esi = 6,
>> + gdb_edi = 7,
>> + gdb_eip = 8,
>> + gdb_eflags = 9,
>> + gdb_cs = 10,
>> + gdb_ss = 11,
>> + gdb_ds = 12,
>> + gdb_es = 13,
>> + gdb_fs = 14,
>> + gdb_gs = 15,
>> + gdb_stmm0 = 16,
>> + gdb_stmm1 = 17,
>> + gdb_stmm2 = 18,
>> + gdb_stmm3 = 19,
>> + gdb_stmm4 = 20,
>> + gdb_stmm5 = 21,
>> + gdb_stmm6 = 22,
>> + gdb_stmm7 = 23,
>> + gdb_fcw = 24,
>> + gdb_fsw = 25,
>> + gdb_ftw = 26,
>> + gdb_fpu_cs = 27,
>> + gdb_ip = 28,
>> + gdb_fpu_ds = 29,
>> + gdb_dp = 30,
>> + gdb_fop = 31,
>> + gdb_xmm0 = 32,
>> + gdb_xmm1 = 33,
>> + gdb_xmm2 = 34,
>> + gdb_xmm3 = 35,
>> + gdb_xmm4 = 36,
>> + gdb_xmm5 = 37,
>> + gdb_xmm6 = 38,
>> + gdb_xmm7 = 39,
>> + gdb_mxcsr = 40,
>> + gdb_mm0 = 41,
>> + gdb_mm1 = 42,
>> + gdb_mm2 = 43,
>> + gdb_mm3 = 44,
>> + gdb_mm4 = 45,
>> + gdb_mm5 = 46,
>> + gdb_mm6 = 47,
>> + gdb_mm7 = 48
>> +};
>> +
>> +static const
>> +uint32_t g_gpr_regnums[k_num_gpr_registers] =
>> +{
>> + gpr_eax,
>> + gpr_ebx,
>> + gpr_ecx,
>> + gpr_edx,
>> + gpr_edi,
>> + gpr_esi,
>> + gpr_ebp,
>> + gpr_esp,
>> + gpr_ss,
>> + gpr_eflags,
>> +#ifdef __FreeBSD__
>> + gpr_orig_ax,
>> +#endif
>> + gpr_eip,
>> + gpr_cs,
>> + gpr_ds,
>> + gpr_es,
>> + gpr_fs,
>> + gpr_gs,
>> +};
>> +
>> +static const uint32_t
>> +g_fpu_regnums[k_num_fpu_registers] =
>> +{
>> + fpu_fcw,
>> + fpu_fsw,
>> + fpu_ftw,
>> + fpu_fop,
>> + fpu_ip,
>> + fpu_cs,
>> + fpu_foo,
>> + fpu_fos,
>> + fpu_mxcsr,
>> + fpu_stmm0,
>> + fpu_stmm1,
>> + fpu_stmm2,
>> + fpu_stmm3,
>> + fpu_stmm4,
>> + fpu_stmm5,
>> + fpu_stmm6,
>> + fpu_stmm7,
>> + fpu_xmm0,
>> + fpu_xmm1,
>> + fpu_xmm2,
>> + fpu_xmm3,
>> + fpu_xmm4,
>> + fpu_xmm5,
>> + fpu_xmm6,
>> + fpu_xmm7,
>> +};
>> +
>> +static const RegisterSet
>> +g_reg_sets[k_num_register_sets] =
>> +{
>> + { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
>> + { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }
>> +};
>> +
>> +// Computes the offset of the given GPR in the user data area.
>> +#define GPR_OFFSET(regname) \
>> + (offsetof(RegisterContext_i386::UserArea, regs) + \
>> + offsetof(RegisterContext_i386::GPR, regname))
>> +
>> +// Computes the offset of the given FPR in the user data area.
>> +#define FPR_OFFSET(regname) \
>> + (offsetof(RegisterContext_i386::UserArea, i387) + \
>> + offsetof(RegisterContext_i386::FPU, regname))
>> +
>> +// Number of bytes needed to represent a GPR.
>> +#define GPR_SIZE(reg) sizeof(((RegisterContext_i386::GPR*)NULL)->reg)
>> +
>> +// Number of bytes needed to represent a FPR.
>> +#define FPR_SIZE(reg) sizeof(((RegisterContext_i386::FPU*)NULL)->reg)
>> +
>> +// Number of bytes needed to represent the i'th FP register.
>> +#define FP_SIZE sizeof(((RegisterContext_i386::MMSReg*)NULL)->bytes)
>> +
>> +// Number of bytes needed to represent an XMM register.
>> +#define XMM_SIZE sizeof(RegisterContext_i386::XMMReg)
>> +
>> +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
>> + { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
>> + eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg } }
>> +
>> +#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \
>> + { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
>> + eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg } }
>> +
>> +#define DEFINE_FP(reg, i) \
>> + { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
>> + eFormatVectorOfUInt8, \
>> + { dwarf_##reg##i, dwarf_##reg##i, \
>> + LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } }
>> +
>> +#define DEFINE_XMM(reg, i) \
>> + { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
>> + eFormatVectorOfUInt8, \
>> + { dwarf_##reg##i, dwarf_##reg##i, \
>> + LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } }
>> +
>> +static RegisterInfo
>> +g_register_infos[k_num_registers] =
>> +{
>> + // General purpose registers.
>> + DEFINE_GPR(eax, NULL, gcc_eax, dwarf_eax, LLDB_INVALID_REGNUM, gdb_eax),
>> + DEFINE_GPR(ebx, NULL, gcc_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, gdb_ebx),
>> + DEFINE_GPR(ecx, NULL, gcc_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, gdb_ecx),
>> + DEFINE_GPR(edx, NULL, gcc_edx, dwarf_edx, LLDB_INVALID_REGNUM, gdb_edx),
>> + DEFINE_GPR(edi, NULL, gcc_edi, dwarf_edi, LLDB_INVALID_REGNUM, gdb_edi),
>> + DEFINE_GPR(esi, NULL, gcc_esi, dwarf_esi, LLDB_INVALID_REGNUM, gdb_esi),
>> + DEFINE_GPR(ebp, "fp", gcc_ebp, dwarf_ebp, LLDB_INVALID_REGNUM, gdb_ebp),
>> + DEFINE_GPR(esp, "sp", gcc_esp, dwarf_esp, LLDB_INVALID_REGNUM, gdb_esp),
>> + DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ss),
>> + DEFINE_GPR(eflags, "flags", gcc_eflags, dwarf_eflags, LLDB_INVALID_REGNUM, gdb_eflags),
>> + DEFINE_GPR(eip, "pc", gcc_eip, dwarf_eip, LLDB_INVALID_REGNUM, gdb_eip),
>> + DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_cs),
>> + DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ds),
>> + DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_es),
>> + DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fs),
>> + DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gs),
>> +
>> + // Floating point registers.
>> + DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fcw),
>> + DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fsw),
>> + DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ftw),
>> + DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fop),
>> + DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ip),
>> + DEFINE_FPR(cs, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs),
>> + DEFINE_FPR(foo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_dp),
>> + DEFINE_FPR(fos, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds),
>> + DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_mxcsr),
>> +
>> + DEFINE_FP(stmm, 0),
>> + DEFINE_FP(stmm, 1),
>> + DEFINE_FP(stmm, 2),
>> + DEFINE_FP(stmm, 3),
>> + DEFINE_FP(stmm, 4),
>> + DEFINE_FP(stmm, 5),
>> + DEFINE_FP(stmm, 6),
>> + DEFINE_FP(stmm, 7),
>> +
>> + // XMM registers
>> + DEFINE_XMM(xmm, 0),
>> + DEFINE_XMM(xmm, 1),
>> + DEFINE_XMM(xmm, 2),
>> + DEFINE_XMM(xmm, 3),
>> + DEFINE_XMM(xmm, 4),
>> + DEFINE_XMM(xmm, 5),
>> + DEFINE_XMM(xmm, 6),
>> + DEFINE_XMM(xmm, 7),
>> +
>> +};
>> +
>> +#ifndef NDEBUG
>> +static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
>> +#endif
>> +
>> +static unsigned GetRegOffset(unsigned reg)
>> +{
>> + assert(reg < k_num_registers && "Invalid register number.");
>> + return g_register_infos[reg].byte_offset;
>> +}
>> +
>> +static unsigned GetRegSize(unsigned reg)
>> +{
>> + assert(reg < k_num_registers && "Invalid register number.");
>> + return g_register_infos[reg].byte_size;
>> +}
>> +
>> +RegisterContext_i386::RegisterContext_i386(Thread &thread,
>> + uint32_t concrete_frame_idx)
>> + : RegisterContextPOSIX(thread, concrete_frame_idx)
>> +{
>> +}
>> +
>> +RegisterContext_i386::~RegisterContext_i386()
>> +{
>> +}
>> +
>> +ProcessMonitor &
>> +RegisterContext_i386::GetMonitor()
>> +{
>> + ProcessPOSIX *process = static_cast<ProcessPOSIX*>(CalculateProcess());
>> + return process->GetMonitor();
>> +}
>> +
>> +void
>> +RegisterContext_i386::Invalidate()
>> +{
>> +}
>> +
>> +void
>> +RegisterContext_i386::InvalidateAllRegisters()
>> +{
>> +}
>> +
>> +size_t
>> +RegisterContext_i386::GetRegisterCount()
>> +{
>> + assert(k_num_register_infos == k_num_registers);
>> + return k_num_registers;
>> +}
>> +
>> +const RegisterInfo *
>> +RegisterContext_i386::GetRegisterInfoAtIndex(uint32_t reg)
>> +{
>> + assert(k_num_register_infos == k_num_registers);
>> + if (reg < k_num_registers)
>> + return &g_register_infos[reg];
>> + else
>> + return NULL;
>> +}
>> +
>> +size_t
>> +RegisterContext_i386::GetRegisterSetCount()
>> +{
>> + return k_num_register_sets;
>> +}
>> +
>> +const RegisterSet *
>> +RegisterContext_i386::GetRegisterSet(uint32_t set)
>> +{
>> + if (set < k_num_register_sets)
>> + return &g_reg_sets[set];
>> + else
>> + return NULL;
>> +}
>> +
>> +unsigned
>> +RegisterContext_i386::GetRegisterIndexFromOffset(unsigned offset)
>> +{
>> + unsigned reg;
>> + for (reg = 0; reg < k_num_registers; reg++)
>> + {
>> + if (g_register_infos[reg].byte_offset == offset)
>> + break;
>> + }
>> + assert(reg < k_num_registers && "Invalid register offset.");
>> + return reg;
>> +}
>> +
>> +const char *
>> +RegisterContext_i386::GetRegisterName(unsigned reg)
>> +{
>> + assert(reg < k_num_registers && "Invalid register offset.");
>> + return g_register_infos[reg].name;
>> +}
>> +
>> +bool
>> +RegisterContext_i386::ReadRegister(const RegisterInfo *reg_info,
>> + RegisterValue &value)
>> +{
>> + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
>> + ProcessMonitor &monitor = GetMonitor();
>> + return monitor.ReadRegisterValue(GetRegOffset(reg), GetRegSize(reg), value);
>> +}
>> +
>> +bool
>> +RegisterContext_i386::ReadAllRegisterValues(DataBufferSP &data_sp)
>> +{
>> + return false;
>> +}
>> +
>> +bool RegisterContext_i386::WriteRegister(const RegisterInfo *reg_info,
>> + const RegisterValue &value)
>> +{
>> + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
>> + ProcessMonitor &monitor = GetMonitor();
>> + return monitor.WriteRegisterValue(GetRegOffset(reg), value);
>> +}
>> +
>> +bool
>> +RegisterContext_i386::WriteAllRegisterValues(const DataBufferSP &data)
>> +{
>> + return false;
>> +}
>> +
>> +bool
>> +RegisterContext_i386::UpdateAfterBreakpoint()
>> +{
>> + // PC points one byte past the int3 responsible for the breakpoint.
>> + lldb::addr_t pc;
>> +
>> + if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
>> + return false;
>> +
>> + SetPC(pc - 1);
>> + return true;
>> +}
>> +
>> +uint32_t
>> +RegisterContext_i386::ConvertRegisterKindToRegisterNumber(uint32_t kind,
>> + uint32_t num)
>> +{
>> + if (kind == eRegisterKindGeneric)
>> + {
>> + switch (num)
>> + {
>> + case LLDB_REGNUM_GENERIC_PC: return gpr_eip;
>> + case LLDB_REGNUM_GENERIC_SP: return gpr_esp;
>> + case LLDB_REGNUM_GENERIC_FP: return gpr_ebp;
>> + case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags;
>> + case LLDB_REGNUM_GENERIC_RA:
>> + default:
>> + return LLDB_INVALID_REGNUM;
>> + }
>> + }
>> +
>> + if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
>> + {
>> + switch (num)
>> + {
>> + case dwarf_eax: return gpr_eax;
>> + case dwarf_edx: return gpr_edx;
>> + case dwarf_ecx: return gpr_ecx;
>> + case dwarf_ebx: return gpr_ebx;
>> + case dwarf_esi: return gpr_esi;
>> + case dwarf_edi: return gpr_edi;
>> + case dwarf_ebp: return gpr_ebp;
>> + case dwarf_esp: return gpr_esp;
>> + case dwarf_eip: return gpr_eip;
>> + case dwarf_xmm0: return fpu_xmm0;
>> + case dwarf_xmm1: return fpu_xmm1;
>> + case dwarf_xmm2: return fpu_xmm2;
>> + case dwarf_xmm3: return fpu_xmm3;
>> + case dwarf_xmm4: return fpu_xmm4;
>> + case dwarf_xmm5: return fpu_xmm5;
>> + case dwarf_xmm6: return fpu_xmm6;
>> + case dwarf_xmm7: return fpu_xmm7;
>> + case dwarf_stmm0: return fpu_stmm0;
>> + case dwarf_stmm1: return fpu_stmm1;
>> + case dwarf_stmm2: return fpu_stmm2;
>> + case dwarf_stmm3: return fpu_stmm3;
>> + case dwarf_stmm4: return fpu_stmm4;
>> + case dwarf_stmm5: return fpu_stmm5;
>> + case dwarf_stmm6: return fpu_stmm6;
>> + case dwarf_stmm7: return fpu_stmm7;
>> + default:
>> + return LLDB_INVALID_REGNUM;
>> + }
>> + }
>> +
>> + if (kind == eRegisterKindGDB)
>> + {
>> + switch (num)
>> + {
>> + case gdb_eax : return gpr_eax;
>> + case gdb_ebx : return gpr_ebx;
>> + case gdb_ecx : return gpr_ecx;
>> + case gdb_edx : return gpr_edx;
>> + case gdb_esi : return gpr_esi;
>> + case gdb_edi : return gpr_edi;
>> + case gdb_ebp : return gpr_ebp;
>> + case gdb_esp : return gpr_esp;
>> + case gdb_eip : return gpr_eip;
>> + case gdb_eflags : return gpr_eflags;
>> + case gdb_cs : return gpr_cs;
>> + case gdb_ss : return gpr_ss;
>> + case gdb_ds : return gpr_ds;
>> + case gdb_es : return gpr_es;
>> + case gdb_fs : return gpr_fs;
>> + case gdb_gs : return gpr_gs;
>> + case gdb_stmm0 : return fpu_stmm0;
>> + case gdb_stmm1 : return fpu_stmm1;
>> + case gdb_stmm2 : return fpu_stmm2;
>> + case gdb_stmm3 : return fpu_stmm3;
>> + case gdb_stmm4 : return fpu_stmm4;
>> + case gdb_stmm5 : return fpu_stmm5;
>> + case gdb_stmm6 : return fpu_stmm6;
>> + case gdb_stmm7 : return fpu_stmm7;
>> + case gdb_fcw : return fpu_fcw;
>> + case gdb_fsw : return fpu_fsw;
>> + case gdb_ftw : return fpu_ftw;
>> + case gdb_fpu_cs : return fpu_cs;
>> + case gdb_ip : return fpu_ip;
>> + case gdb_fpu_ds : return fpu_fos;
>> + case gdb_dp : return fpu_foo;
>> + case gdb_fop : return fpu_fop;
>> + case gdb_xmm0 : return fpu_xmm0;
>> + case gdb_xmm1 : return fpu_xmm1;
>> + case gdb_xmm2 : return fpu_xmm2;
>> + case gdb_xmm3 : return fpu_xmm3;
>> + case gdb_xmm4 : return fpu_xmm4;
>> + case gdb_xmm5 : return fpu_xmm5;
>> + case gdb_xmm6 : return fpu_xmm6;
>> + case gdb_xmm7 : return fpu_xmm7;
>> + case gdb_mxcsr : return fpu_mxcsr;
>> + default:
>> + return LLDB_INVALID_REGNUM;
>> + }
>> + }
>> + else if (kind == eRegisterKindLLDB)
>> + {
>> + return num;
>> + }
>> +
>> + return LLDB_INVALID_REGNUM;
>> +}
>> +
>> +bool
>> +RegisterContext_i386::HardwareSingleStep(bool enable)
>> +{
>> + enum { TRACE_BIT = 0x100 };
>> + uint64_t eflags;
>> +
>> + if ((eflags = ReadRegisterAsUnsigned(gpr_eflags, -1UL)) == -1UL)
>> + return false;
>> +
>> + if (enable)
>> + {
>> + if (eflags & TRACE_BIT)
>> + return true;
>> +
>> + eflags |= TRACE_BIT;
>> + }
>> + else
>> + {
>> + if (!(eflags & TRACE_BIT))
>> + return false;
>> +
>> + eflags &= ~TRACE_BIT;
>> + }
>> +
>> + return WriteRegisterFromUnsigned(gpr_eflags, eflags);
>> +}
>> +
>> +void
>> +RegisterContext_i386::LogGPR(const char *title)
>> +{
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
>> + if (log)
>> + {
>> + if (title)
>> + log->Printf ("%s", title);
>> + for (uint32_t i=0; i<k_num_gpr_registers; i++)
>> + {
>> + uint32_t reg = gpr_eax + i;
>> + log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&user.regs)[reg]);
>> + }
>> + }
>> +}
>> +
>> +bool
>> +RegisterContext_i386::ReadGPR()
>> +{
>> + bool result;
>> +
>> + ProcessMonitor &monitor = GetMonitor();
>> + result = monitor.ReadGPR(&user.regs);
>> + LogGPR("RegisterContext_i386::ReadGPR()");
>> + return result;
>> +}
>> +
>> +bool
>> +RegisterContext_i386::ReadFPR()
>> +{
>> + ProcessMonitor &monitor = GetMonitor();
>> + return monitor.ReadFPR(&user.i387);
>> +}
>> Index: source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
>> ===================================================================
>> --- source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp (revision 0)
>> +++ source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp (revision 0)
>> @@ -0,0 +1,195 @@
>> +//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +#include "ProcessPOSIXLog.h"
>> +
>> +#include "lldb/Interpreter/Args.h"
>> +#include "lldb/Core/StreamFile.h"
>> +
>> +#include "ProcessPOSIX.h"
>> +#include "ProcessPOSIXLog.h"
>> +
>> +using namespace lldb;
>> +using namespace lldb_private;
>> +
>> +
>> +// We want to avoid global constructors where code needs to be run so here we
>> +// control access to our static g_log_sp by hiding it in a singleton function
>> +// that will construct the static g_lob_sp the first time this function is
>> +// called.
>> +static LogSP &
>> +GetLog ()
>> +{
>> + static LogSP g_log_sp;
>> + return g_log_sp;
>> +}
>> +
>> +LogSP
>> +ProcessPOSIXLog::GetLogIfAllCategoriesSet (uint32_t mask)
>> +{
>> + LogSP log(GetLog ());
>> + if (log && mask)
>> + {
>> + uint32_t log_mask = log->GetMask().Get();
>> + if ((log_mask & mask) != mask)
>> + return LogSP();
>> + }
>> + return log;
>> +}
>> +
>> +void
>> +ProcessPOSIXLog::DisableLog (Args &args, Stream *feedback_strm)
>> +{
>> + LogSP log (GetLog ());
>> + if (log)
>> + {
>> + uint32_t flag_bits = 0;
>> +
>> + const size_t argc = args.GetArgumentCount ();
>> + if (argc > 0)
>> + {
>> + flag_bits = log->GetMask().Get();
>> + for (size_t i = 0; i < argc; ++i)
>> + {
>> + const char *arg = args.GetArgumentAtIndex (i);
>> +
>> +
>> + if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~POSIX_LOG_ALL;
>> + else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~POSIX_LOG_ASYNC;
>> + else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~POSIX_LOG_BREAKPOINTS;
>> + else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~POSIX_LOG_COMM;
>> + else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~POSIX_LOG_DEFAULT;
>> + else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~POSIX_LOG_PACKETS;
>> + else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY;
>> + else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_SHORT;
>> + else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_LONG;
>> + else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~POSIX_LOG_PROCESS;
>> + else if (::strcasecmp (arg, "ptrace") == 0 ) flag_bits &= ~POSIX_LOG_PTRACE;
>> + else if (::strcasecmp (arg, "registers") == 0 ) flag_bits &= ~POSIX_LOG_REGISTERS;
>> + else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~POSIX_LOG_STEP;
>> + else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~POSIX_LOG_THREAD;
>> + else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~POSIX_LOG_VERBOSE;
>> + else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~POSIX_LOG_WATCHPOINTS;
>> + else
>> + {
>> + feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
>> + ListLogCategories (feedback_strm);
>> + }
>> +
>> + }
>> + }
>> +
>> + if (flag_bits == 0)
>> + GetLog ().reset();
>> + else
>> + log->GetMask().Reset (flag_bits);
>> + }
>> +
>> + return;
>> +}
>> +
>> +LogSP
>> +ProcessPOSIXLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm)
>> +{
>> + // Try see if there already is a log - that way we can reuse its settings.
>> + // We could reuse the log in toto, but we don't know that the stream is the same.
>> + uint32_t flag_bits = 0;
>> + LogSP log(GetLog ());
>> + if (log)
>> + flag_bits = log->GetMask().Get();
>> +
>> + // Now make a new log with this stream if one was provided
>> + if (log_stream_sp)
>> + {
>> + log = make_shared<Log>(log_stream_sp);
>> + GetLog () = log;
>> + }
>> +
>> + if (log)
>> + {
>> + bool got_unknown_category = false;
>> + const size_t argc = args.GetArgumentCount();
>> + for (size_t i=0; i<argc; ++i)
>> + {
>> + const char *arg = args.GetArgumentAtIndex(i);
>> +
>> + if (::strcasecmp (arg, "all") == 0 ) flag_bits |= POSIX_LOG_ALL;
>> + else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= POSIX_LOG_ASYNC;
>> + else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= POSIX_LOG_BREAKPOINTS;
>> + else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= POSIX_LOG_COMM;
>> + else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= POSIX_LOG_DEFAULT;
>> + else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= POSIX_LOG_PACKETS;
>> + else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= POSIX_LOG_MEMORY;
>> + else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= POSIX_LOG_MEMORY_DATA_SHORT;
>> + else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= POSIX_LOG_MEMORY_DATA_LONG;
>> + else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= POSIX_LOG_PROCESS;
>> + else if (::strcasecmp (arg, "ptrace") == 0 ) flag_bits |= POSIX_LOG_PTRACE;
>> + else if (::strcasecmp (arg, "registers") == 0 ) flag_bits |= POSIX_LOG_REGISTERS;
>> + else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= POSIX_LOG_STEP;
>> + else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= POSIX_LOG_THREAD;
>> + else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= POSIX_LOG_VERBOSE;
>> + else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= POSIX_LOG_WATCHPOINTS;
>> + else
>> + {
>> + feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
>> + if (got_unknown_category == false)
>> + {
>> + got_unknown_category = true;
>> + ListLogCategories (feedback_strm);
>> + }
>> + }
>> + }
>> + if (flag_bits == 0)
>> + flag_bits = POSIX_LOG_DEFAULT;
>> + log->GetMask().Reset(flag_bits);
>> + log->GetOptions().Reset(log_options);
>> + }
>> + return log;
>> +}
>> +
>> +void
>> +ProcessPOSIXLog::ListLogCategories (Stream *strm)
>> +{
>> + strm->Printf ("Logging categories for '%s':\n"
>> + " all - turn on all available logging categories\n"
>> + " async - log asynchronous activity\n"
>> + " break - log breakpoints\n"
>> + " communication - log communication activity\n"
>> + " default - enable the default set of logging categories for liblldb\n"
>> + " packets - log gdb remote packets\n"
>> + " memory - log memory reads and writes\n"
>> + " data-short - log memory bytes for memory reads and writes for short transactions only\n"
>> + " data-long - log memory bytes for memory reads and writes for all transactions\n"
>> + " process - log process events and activities\n"
>> +#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
>> + " ptrace - log all calls to ptrace\n"
>> +#endif
>> + " registers - log register read/writes\n"
>> + " thread - log thread events and activities\n"
>> + " step - log step related activities\n"
>> + " verbose - enable verbose logging\n"
>> + " watch - log watchpoint related activities\n", ProcessPOSIXLog::m_pluginname);
>> +}
>> +
>> +
>> +void
>> +ProcessPOSIXLog::LogIf (uint32_t mask, const char *format, ...)
>> +{
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (mask));
>> + if (log)
>> + {
>> + va_list args;
>> + va_start (args, format);
>> + log->VAPrintf (format, args);
>> + va_end (args);
>> + }
>> +}
>> +
>> +int ProcessPOSIXLog::m_nestinglevel;
>> +const char *ProcessPOSIXLog::m_pluginname = "";
>> Index: source/Plugins/Process/POSIX/ProcessPOSIX.h
>> ===================================================================
>> --- source/Plugins/Process/POSIX/ProcessPOSIX.h (revision 0)
>> +++ source/Plugins/Process/POSIX/ProcessPOSIX.h (revision 0)
>> @@ -0,0 +1,180 @@
>> +//===-- ProcessPOSIX.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_ProcessPOSIX_H_
>> +#define liblldb_ProcessPOSIX_H_
>> +
>> +// C Includes
>> +
>> +// C++ Includes
>> +#include <queue>
>> +
>> +// Other libraries and framework includes
>> +#include "lldb/Target/Process.h"
>> +#include "lldb/Target/UnixSignals.h"
>> +#include "ProcessMessage.h"
>> +
>> +class ProcessMonitor;
>> +
>> +class ProcessPOSIX :
>> + public lldb_private::Process
>> +{
>> +public:
>> +
>> + //------------------------------------------------------------------
>> + // Constructors and destructors
>> + //------------------------------------------------------------------
>> + ProcessPOSIX(lldb_private::Target& target,
>> + lldb_private::Listener &listener);
>> +
>> + virtual
>> + ~ProcessPOSIX();
>> +
>> + //------------------------------------------------------------------
>> + // 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();
>> +
>> + virtual uint32_t
>> + UpdateThreadList(lldb_private::ThreadList &old_thread_list,
>> + lldb_private::ThreadList &new_thread_list) = 0;
>> +
>> + 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);
>> +
>> + //--------------------------------------------------------------------------
>> + // ProcessPOSIX 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();
>> +
>> + const char *
>> + GetFilePath(const lldb_private::ProcessLaunchInfo::FileAction *file_action,
>> + const char *default_path);
>> +
>> +protected:
>> + /// 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<ProcessMessage> 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;
>> +
>> + /// OS-specific signal set.
>> + lldb_private::UnixSignals m_signals;
>> +
>> + /// Returns true if the process has exited.
>> + bool HasExited();
>> +
>> + /// Returns true if the process is stopped.
>> + bool IsStopped();
>> +
>> + typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
>> + MMapMap m_addr_to_mmap_size;
>> +};
>> +
>> +#endif // liblldb_MacOSXProcess_H_
>> Index: source/Plugins/Process/POSIX/RegisterContext_i386.h
>> ===================================================================
>> --- source/Plugins/Process/POSIX/RegisterContext_i386.h (revision 0)
>> +++ source/Plugins/Process/POSIX/RegisterContext_i386.h (revision 0)
>> @@ -0,0 +1,169 @@
>> +//===-- RegisterContext_i386.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_RegisterContext_i386_h_
>> +#define liblldb_RegisterContext_i386_h_
>> +
>> +// C Includes
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +// Project includes
>> +#include "lldb/Core/Log.h"
>> +#include "RegisterContextPOSIX.h"
>> +
>> +class RegisterContext_i386 : public RegisterContextPOSIX
>> +{
>> +public:
>> + RegisterContext_i386(lldb_private::Thread &thread,
>> + uint32_t concreate_frame_idx);
>> +
>> + ~RegisterContext_i386();
>> +
>> + 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);
>> +
>> + bool
>> + ReadRegisterValue(uint32_t reg, lldb_private::Scalar &value);
>> +
>> + bool
>> + ReadRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data);
>> +
>> + virtual bool
>> + ReadRegister(const lldb_private::RegisterInfo *reg_info,
>> + lldb_private::RegisterValue &value);
>> +
>> + bool
>> + ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
>> +
>> + bool
>> + WriteRegisterValue(uint32_t reg, const lldb_private::Scalar &value);
>> +
>> + bool
>> + WriteRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data,
>> + uint32_t data_offset = 0);
>> +
>> + 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
>> + {
>> + uint32_t ebx;
>> + uint32_t ecx;
>> + uint32_t edx;
>> + uint32_t esi;
>> + uint32_t edi;
>> + uint32_t ebp;
>> + uint32_t eax;
>> + uint32_t ds;
>> + uint32_t es;
>> + uint32_t fs;
>> + uint32_t gs;
>> + uint32_t orig_ax;
>> + uint32_t eip;
>> + uint32_t cs;
>> + uint32_t eflags;
>> + uint32_t esp;
>> + uint32_t ss;
>> + };
>> +
>> + struct MMSReg
>> + {
>> + uint8_t bytes[8];
>> + };
>> +
>> + struct XMMReg
>> + {
>> + uint8_t bytes[16];
>> + };
>> +
>> + struct FPU
>> + {
>> + uint16_t fcw;
>> + uint16_t fsw;
>> + uint16_t ftw;
>> + uint16_t fop;
>> + uint32_t ip;
>> + uint32_t cs;
>> + uint32_t foo;
>> + uint32_t fos;
>> + uint32_t mxcsr;
>> + uint32_t reserved;
>> + MMSReg stmm[8];
>> + XMMReg xmm[8];
>> + uint32_t pad[56];
>> + };
>> +
>> + // A user area like this no longer exists on FreeBSD
>> + // making this a Linux artifact. Nonetheless, it is safe
>> + // leaving it here while the code is being cleaned up and generalized.
>> +
>> + struct UserArea
>> + {
>> + GPR regs; // General purpose registers.
>> + int32_t fpvalid; // True if FPU is being used.
>> + FPU i387; // FPU registers.
>> + uint32_t tsize; // Text segment size.
>> + uint32_t dsize; // Data segment size.
>> + uint32_t ssize; // Stack segment size.
>> + uint32_t start_code; // VM address of text.
>> + uint32_t start_stack; // VM address of stack bottom (top in rsp).
>> + int32_t signal; // Signal causing core dump.
>> + int32_t reserved; // Unused.
>> + uint32_t ar0; // Location of GPR's.
>> + FPU* fpstate; // Location of FPR's.
>> + uint32_t magic; // Identifier for core dumps.
>> + char u_comm[32]; // Command causing core dump.
>> + uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
>> + };
>> +private:
>> + UserArea user;
>> +
>> + ProcessMonitor &GetMonitor();
>> +
>> + void LogGPR(const char *title);
>> +
>> + bool ReadGPR();
>> + bool ReadFPR();
>> +};
>> +
>> +#endif // #ifndef liblldb_RegisterContext_i386_h_
>> Index: source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
>> ===================================================================
>> --- source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp (revision 0)
>> +++ source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp (revision 0)
>> @@ -0,0 +1,757 @@
>> +//===-- RegisterContext_x86_64.cpp -------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +#include <cstring>
>> +#include <errno.h>
>> +#include <stdint.h>
>> +
>> +#include "lldb/Core/DataBufferHeap.h"
>> +#include "lldb/Core/DataExtractor.h"
>> +#include "lldb/Core/Scalar.h"
>> +#include "lldb/Target/Thread.h"
>> +#include "lldb/Host/Endian.h"
>> +
>> +#include "ProcessPOSIX.h"
>> +#include "ProcessMonitor.h"
>> +#include "RegisterContext_x86_64.h"
>> +
>> +using namespace lldb_private;
>> +using namespace lldb;
>> +
>> +// Internal codes for all x86_64 registers.
>> +enum
>> +{
>> + k_first_gpr,
>> + gpr_rax = k_first_gpr,
>> + gpr_rbx,
>> + gpr_rcx,
>> + gpr_rdx,
>> + gpr_rdi,
>> + gpr_rsi,
>> + gpr_rbp,
>> + gpr_rsp,
>> + gpr_r8,
>> + gpr_r9,
>> + gpr_r10,
>> + gpr_r11,
>> + gpr_r12,
>> + gpr_r13,
>> + gpr_r14,
>> + gpr_r15,
>> + gpr_rip,
>> + gpr_rflags,
>> + gpr_cs,
>> + gpr_fs,
>> + gpr_gs,
>> + gpr_ss,
>> + gpr_ds,
>> + gpr_es,
>> + k_last_gpr = gpr_es,
>> +
>> + k_first_fpr,
>> + fpu_fcw = k_first_fpr,
>> + fpu_fsw,
>> + fpu_ftw,
>> + fpu_fop,
>> + fpu_ip,
>> + fpu_cs,
>> + fpu_dp,
>> + fpu_ds,
>> + fpu_mxcsr,
>> + fpu_mxcsrmask,
>> + fpu_stmm0,
>> + fpu_stmm1,
>> + fpu_stmm2,
>> + fpu_stmm3,
>> + fpu_stmm4,
>> + fpu_stmm5,
>> + fpu_stmm6,
>> + fpu_stmm7,
>> + fpu_xmm0,
>> + fpu_xmm1,
>> + fpu_xmm2,
>> + fpu_xmm3,
>> + fpu_xmm4,
>> + fpu_xmm5,
>> + fpu_xmm6,
>> + fpu_xmm7,
>> + fpu_xmm8,
>> + fpu_xmm9,
>> + fpu_xmm10,
>> + fpu_xmm11,
>> + fpu_xmm12,
>> + fpu_xmm13,
>> + fpu_xmm14,
>> + fpu_xmm15,
>> + k_last_fpr = fpu_xmm15,
>> +
>> + k_num_registers,
>> + k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
>> + k_num_fpu_registers = k_last_fpr - k_first_fpr + 1
>> +};
>> +
>> +// Number of register sets provided by this context.
>> +enum
>> +{
>> + k_num_register_sets = 2
>> +};
>> +
>> +enum gcc_dwarf_regnums
>> +{
>> + gcc_dwarf_gpr_rax = 0,
>> + gcc_dwarf_gpr_rdx,
>> + gcc_dwarf_gpr_rcx,
>> + gcc_dwarf_gpr_rbx,
>> + gcc_dwarf_gpr_rsi,
>> + gcc_dwarf_gpr_rdi,
>> + gcc_dwarf_gpr_rbp,
>> + gcc_dwarf_gpr_rsp,
>> + gcc_dwarf_gpr_r8,
>> + gcc_dwarf_gpr_r9,
>> + gcc_dwarf_gpr_r10,
>> + gcc_dwarf_gpr_r11,
>> + gcc_dwarf_gpr_r12,
>> + gcc_dwarf_gpr_r13,
>> + gcc_dwarf_gpr_r14,
>> + gcc_dwarf_gpr_r15,
>> + gcc_dwarf_gpr_rip,
>> + gcc_dwarf_fpu_xmm0,
>> + gcc_dwarf_fpu_xmm1,
>> + gcc_dwarf_fpu_xmm2,
>> + gcc_dwarf_fpu_xmm3,
>> + gcc_dwarf_fpu_xmm4,
>> + gcc_dwarf_fpu_xmm5,
>> + gcc_dwarf_fpu_xmm6,
>> + gcc_dwarf_fpu_xmm7,
>> + gcc_dwarf_fpu_xmm8,
>> + gcc_dwarf_fpu_xmm9,
>> + gcc_dwarf_fpu_xmm10,
>> + gcc_dwarf_fpu_xmm11,
>> + gcc_dwarf_fpu_xmm12,
>> + gcc_dwarf_fpu_xmm13,
>> + gcc_dwarf_fpu_xmm14,
>> + gcc_dwarf_fpu_xmm15,
>> + gcc_dwarf_fpu_stmm0,
>> + gcc_dwarf_fpu_stmm1,
>> + gcc_dwarf_fpu_stmm2,
>> + gcc_dwarf_fpu_stmm3,
>> + gcc_dwarf_fpu_stmm4,
>> + gcc_dwarf_fpu_stmm5,
>> + gcc_dwarf_fpu_stmm6,
>> + gcc_dwarf_fpu_stmm7
>> +};
>> +
>> +enum gdb_regnums
>> +{
>> + gdb_gpr_rax = 0,
>> + gdb_gpr_rbx = 1,
>> + gdb_gpr_rcx = 2,
>> + gdb_gpr_rdx = 3,
>> + gdb_gpr_rsi = 4,
>> + gdb_gpr_rdi = 5,
>> + gdb_gpr_rbp = 6,
>> + gdb_gpr_rsp = 7,
>> + gdb_gpr_r8 = 8,
>> + gdb_gpr_r9 = 9,
>> + gdb_gpr_r10 = 10,
>> + gdb_gpr_r11 = 11,
>> + gdb_gpr_r12 = 12,
>> + gdb_gpr_r13 = 13,
>> + gdb_gpr_r14 = 14,
>> + gdb_gpr_r15 = 15,
>> + gdb_gpr_rip = 16,
>> + gdb_gpr_rflags = 17,
>> + gdb_gpr_cs = 18,
>> + gdb_gpr_ss = 19,
>> + gdb_gpr_ds = 20,
>> + gdb_gpr_es = 21,
>> + gdb_gpr_fs = 22,
>> + gdb_gpr_gs = 23,
>> + gdb_fpu_stmm0 = 24,
>> + gdb_fpu_stmm1 = 25,
>> + gdb_fpu_stmm2 = 26,
>> + gdb_fpu_stmm3 = 27,
>> + gdb_fpu_stmm4 = 28,
>> + gdb_fpu_stmm5 = 29,
>> + gdb_fpu_stmm6 = 30,
>> + gdb_fpu_stmm7 = 31,
>> + gdb_fpu_fcw = 32,
>> + gdb_fpu_fsw = 33,
>> + gdb_fpu_ftw = 34,
>> + gdb_fpu_cs = 35,
>> + gdb_fpu_ip = 36,
>> + gdb_fpu_ds = 37,
>> + gdb_fpu_dp = 38,
>> + gdb_fpu_fop = 39,
>> + gdb_fpu_xmm0 = 40,
>> + gdb_fpu_xmm1 = 41,
>> + gdb_fpu_xmm2 = 42,
>> + gdb_fpu_xmm3 = 43,
>> + gdb_fpu_xmm4 = 44,
>> + gdb_fpu_xmm5 = 45,
>> + gdb_fpu_xmm6 = 46,
>> + gdb_fpu_xmm7 = 47,
>> + gdb_fpu_xmm8 = 48,
>> + gdb_fpu_xmm9 = 49,
>> + gdb_fpu_xmm10 = 50,
>> + gdb_fpu_xmm11 = 51,
>> + gdb_fpu_xmm12 = 52,
>> + gdb_fpu_xmm13 = 53,
>> + gdb_fpu_xmm14 = 54,
>> + gdb_fpu_xmm15 = 55,
>> + gdb_fpu_mxcsr = 56
>> +};
>> +
>> +static const
>> +uint32_t g_gpr_regnums[k_num_gpr_registers] =
>> +{
>> + gpr_rax,
>> + gpr_rbx,
>> + gpr_rcx,
>> + gpr_rdx,
>> + gpr_rdi,
>> + gpr_rsi,
>> + gpr_rbp,
>> + gpr_rsp,
>> + gpr_r8,
>> + gpr_r9,
>> + gpr_r10,
>> + gpr_r11,
>> + gpr_r12,
>> + gpr_r13,
>> + gpr_r14,
>> + gpr_r15,
>> + gpr_rip,
>> + gpr_rflags,
>> + gpr_cs,
>> + gpr_fs,
>> + gpr_gs,
>> + gpr_ss,
>> + gpr_ds,
>> + gpr_es
>> +};
>> +
>> +static const uint32_t
>> +g_fpu_regnums[k_num_fpu_registers] =
>> +{
>> + fpu_fcw,
>> + fpu_fsw,
>> + fpu_ftw,
>> + fpu_fop,
>> + fpu_ip,
>> + fpu_cs,
>> + fpu_dp,
>> + fpu_ds,
>> + fpu_mxcsr,
>> + fpu_mxcsrmask,
>> + fpu_stmm0,
>> + fpu_stmm1,
>> + fpu_stmm2,
>> + fpu_stmm3,
>> + fpu_stmm4,
>> + fpu_stmm5,
>> + fpu_stmm6,
>> + fpu_stmm7,
>> + fpu_xmm0,
>> + fpu_xmm1,
>> + fpu_xmm2,
>> + fpu_xmm3,
>> + fpu_xmm4,
>> + fpu_xmm5,
>> + fpu_xmm6,
>> + fpu_xmm7,
>> + fpu_xmm8,
>> + fpu_xmm9,
>> + fpu_xmm10,
>> + fpu_xmm11,
>> + fpu_xmm12,
>> + fpu_xmm13,
>> + fpu_xmm14,
>> + fpu_xmm15
>> +};
>> +
>> +static const RegisterSet
>> +g_reg_sets[k_num_register_sets] =
>> +{
>> + { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
>> + { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }
>> +};
>> +
>> +// Computes the offset of the given GPR in the user data area.
>> +#define GPR_OFFSET(regname) \
>> + (offsetof(RegisterContext_x86_64::UserArea, regs) + \
>> + offsetof(GPR, regname))
>> +
>> +// Computes the offset of the given FPR in the user data area.
>> +#define FPR_OFFSET(regname) \
>> + (offsetof(RegisterContext_x86_64::UserArea, i387) + \
>> + offsetof(RegisterContext_x86_64::FPU, regname))
>> +
>> +// Number of bytes needed to represent a GPR.
>> +#define GPR_SIZE(reg) sizeof(((GPR*)NULL)->reg)
>> +
>> +// Number of bytes needed to represent a FPR.
>> +#define FPR_SIZE(reg) sizeof(((RegisterContext_x86_64::FPU*)NULL)->reg)
>> +
>> +// Number of bytes needed to represent the i'th FP register.
>> +#define FP_SIZE sizeof(((RegisterContext_x86_64::MMSReg*)NULL)->bytes)
>> +
>> +// Number of bytes needed to represent an XMM register.
>> +#define XMM_SIZE sizeof(RegisterContext_x86_64::XMMReg)
>> +
>> +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
>> + { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
>> + eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg } }
>> +
>> +#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \
>> + { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
>> + eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg } }
>> +
>> +#define DEFINE_FP(reg, i) \
>> + { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
>> + eFormatVectorOfUInt8, \
>> + { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \
>> + LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i } }
>> +
>> +#define DEFINE_XMM(reg, i) \
>> + { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
>> + eFormatVectorOfUInt8, \
>> + { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \
>> + LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i } }
>> +
>> +#define REG_CONTEXT_SIZE (sizeof(GPR) + sizeof(RegisterContext_x86_64::FPU))
>> +
>> +static RegisterInfo
>> +g_register_infos[k_num_registers] =
>> +{
>> + // General purpose registers.
>> + DEFINE_GPR(rax, NULL, gcc_dwarf_gpr_rax, gcc_dwarf_gpr_rax, LLDB_INVALID_REGNUM, gdb_gpr_rax),
>> + DEFINE_GPR(rbx, NULL, gcc_dwarf_gpr_rbx, gcc_dwarf_gpr_rbx, LLDB_INVALID_REGNUM, gdb_gpr_rbx),
>> + DEFINE_GPR(rcx, NULL, gcc_dwarf_gpr_rcx, gcc_dwarf_gpr_rcx, LLDB_INVALID_REGNUM, gdb_gpr_rcx),
>> + DEFINE_GPR(rdx, NULL, gcc_dwarf_gpr_rdx, gcc_dwarf_gpr_rdx, LLDB_INVALID_REGNUM, gdb_gpr_rdx),
>> + DEFINE_GPR(rdi, NULL, gcc_dwarf_gpr_rdi, gcc_dwarf_gpr_rdi, LLDB_INVALID_REGNUM, gdb_gpr_rdi),
>> + DEFINE_GPR(rsi, NULL, gcc_dwarf_gpr_rsi, gcc_dwarf_gpr_rsi, LLDB_INVALID_REGNUM, gdb_gpr_rsi),
>> + DEFINE_GPR(rbp, "fp", gcc_dwarf_gpr_rbp, gcc_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP, gdb_gpr_rbp),
>> + DEFINE_GPR(rsp, "sp", gcc_dwarf_gpr_rsp, gcc_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP, gdb_gpr_rsp),
>> + DEFINE_GPR(r8, NULL, gcc_dwarf_gpr_r8, gcc_dwarf_gpr_r8, LLDB_INVALID_REGNUM, gdb_gpr_r8),
>> + DEFINE_GPR(r9, NULL, gcc_dwarf_gpr_r9, gcc_dwarf_gpr_r9, LLDB_INVALID_REGNUM, gdb_gpr_r9),
>> + DEFINE_GPR(r10, NULL, gcc_dwarf_gpr_r10, gcc_dwarf_gpr_r10, LLDB_INVALID_REGNUM, gdb_gpr_r10),
>> + DEFINE_GPR(r11, NULL, gcc_dwarf_gpr_r11, gcc_dwarf_gpr_r11, LLDB_INVALID_REGNUM, gdb_gpr_r11),
>> + DEFINE_GPR(r12, NULL, gcc_dwarf_gpr_r12, gcc_dwarf_gpr_r12, LLDB_INVALID_REGNUM, gdb_gpr_r12),
>> + DEFINE_GPR(r13, NULL, gcc_dwarf_gpr_r13, gcc_dwarf_gpr_r13, LLDB_INVALID_REGNUM, gdb_gpr_r13),
>> + DEFINE_GPR(r14, NULL, gcc_dwarf_gpr_r14, gcc_dwarf_gpr_r14, LLDB_INVALID_REGNUM, gdb_gpr_r14),
>> + DEFINE_GPR(r15, NULL, gcc_dwarf_gpr_r15, gcc_dwarf_gpr_r15, LLDB_INVALID_REGNUM, gdb_gpr_r15),
>> + DEFINE_GPR(rip, "pc", gcc_dwarf_gpr_rip, gcc_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC, gdb_gpr_rip),
>> + DEFINE_GPR(rflags, "flags", LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_gpr_rflags),
>> + DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_cs),
>> + DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_fs),
>> + DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_gs),
>> + DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ss),
>> + DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ds),
>> + DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_es),
>> +
>> + // i387 Floating point registers.
>> + DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fcw),
>> + DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fsw),
>> + DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ftw),
>> + DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fop),
>> + DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ip),
>> + // FIXME: Extract segment from ip.
>> + DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs),
>> + DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_dp),
>> + // FIXME: Extract segment from dp.
>> + DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds),
>> + DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_mxcsr),
>> + DEFINE_FPR(mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
>> +
>> + // FP registers.
>> + DEFINE_FP(stmm, 0),
>> + DEFINE_FP(stmm, 1),
>> + DEFINE_FP(stmm, 2),
>> + DEFINE_FP(stmm, 3),
>> + DEFINE_FP(stmm, 4),
>> + DEFINE_FP(stmm, 5),
>> + DEFINE_FP(stmm, 6),
>> + DEFINE_FP(stmm, 7),
>> +
>> + // XMM registers
>> + DEFINE_XMM(xmm, 0),
>> + DEFINE_XMM(xmm, 1),
>> + DEFINE_XMM(xmm, 2),
>> + DEFINE_XMM(xmm, 3),
>> + DEFINE_XMM(xmm, 4),
>> + DEFINE_XMM(xmm, 5),
>> + DEFINE_XMM(xmm, 6),
>> + DEFINE_XMM(xmm, 7),
>> + DEFINE_XMM(xmm, 8),
>> + DEFINE_XMM(xmm, 9),
>> + DEFINE_XMM(xmm, 10),
>> + DEFINE_XMM(xmm, 11),
>> + DEFINE_XMM(xmm, 12),
>> + DEFINE_XMM(xmm, 13),
>> + DEFINE_XMM(xmm, 14),
>> + DEFINE_XMM(xmm, 15)
>> +};
>> +
>> +static unsigned GetRegOffset(unsigned reg)
>> +{
>> + assert(reg < k_num_registers && "Invalid register number.");
>> + return g_register_infos[reg].byte_offset;
>> +}
>> +
>> +static unsigned GetRegSize(unsigned reg)
>> +{
>> + assert(reg < k_num_registers && "Invalid register number.");
>> + return g_register_infos[reg].byte_size;
>> +}
>> +
>> +static bool IsGPR(unsigned reg)
>> +{
>> + return reg <= k_last_gpr; // GPR's come first.
>> +}
>> +
>> +static bool IsFPR(unsigned reg)
>> +{
>> + return (k_first_fpr <= reg && reg <= k_last_fpr);
>> +}
>> +
>> +RegisterContext_x86_64::RegisterContext_x86_64(Thread &thread,
>> + uint32_t concrete_frame_idx)
>> + : RegisterContextPOSIX(thread, concrete_frame_idx)
>> +{
>> +}
>> +
>> +RegisterContext_x86_64::~RegisterContext_x86_64()
>> +{
>> +}
>> +
>> +ProcessMonitor &
>> +RegisterContext_x86_64::GetMonitor()
>> +{
>> + ProcessPOSIX *process = static_cast<ProcessPOSIX*>(CalculateProcess());
>> + return process->GetMonitor();
>> +}
>> +
>> +void
>> +RegisterContext_x86_64::Invalidate()
>> +{
>> +}
>> +
>> +void
>> +RegisterContext_x86_64::InvalidateAllRegisters()
>> +{
>> +}
>> +
>> +size_t
>> +RegisterContext_x86_64::GetRegisterCount()
>> +{
>> + return k_num_registers;
>> +}
>> +
>> +const RegisterInfo *
>> +RegisterContext_x86_64::GetRegisterInfoAtIndex(uint32_t reg)
>> +{
>> + if (reg < k_num_registers)
>> + return &g_register_infos[reg];
>> + else
>> + return NULL;
>> +}
>> +
>> +size_t
>> +RegisterContext_x86_64::GetRegisterSetCount()
>> +{
>> + return k_num_register_sets;
>> +}
>> +
>> +const RegisterSet *
>> +RegisterContext_x86_64::GetRegisterSet(uint32_t set)
>> +{
>> + if (set < k_num_register_sets)
>> + return &g_reg_sets[set];
>> + else
>> + return NULL;
>> +}
>> +
>> +unsigned
>> +RegisterContext_x86_64::GetRegisterIndexFromOffset(unsigned offset)
>> +{
>> + unsigned reg;
>> + for (reg = 0; reg < k_num_registers; reg++)
>> + {
>> + if (g_register_infos[reg].byte_offset == offset)
>> + break;
>> + }
>> + assert(reg < k_num_registers && "Invalid register offset.");
>> + return reg;
>> +}
>> +
>> +const char *
>> +RegisterContext_x86_64::GetRegisterName(unsigned reg)
>> +{
>> + assert(reg < k_num_registers && "Invalid register offset.");
>> + return g_register_infos[reg].name;
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::ReadRegister(const RegisterInfo *reg_info,
>> + RegisterValue &value)
>> +{
>> + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
>> + ProcessMonitor &monitor = GetMonitor();
>> + return monitor.ReadRegisterValue(GetRegOffset(reg), GetRegSize(reg), value);
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp)
>> +{
>> + data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
>> + if (data_sp && ReadGPR () && ReadFPR ())
>> + {
>> + uint8_t *dst = data_sp->GetBytes();
>> + ::memcpy (dst, &user.regs, sizeof(user.regs));
>> + dst += sizeof(user.regs);
>> +
>> + ::memcpy (dst, &user.i387, sizeof(user.i387));
>> + return true;
>> + }
>> + return false;
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg_info,
>> + const lldb_private::RegisterValue &value)
>> +{
>> + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
>> + ProcessMonitor &monitor = GetMonitor();
>> + return monitor.WriteRegisterValue(GetRegOffset(reg), value);
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp)
>> +{
>> + if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
>> + {
>> + const uint8_t *src = data_sp->GetBytes();
>> + ::memcpy (&user.regs, src, sizeof(user.regs));
>> + src += sizeof(user.regs);
>> +
>> + ::memcpy (&user.i387, src, sizeof(user.i387));
>> + return WriteGPR() & WriteFPR();
>> + }
>> + return false;
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::UpdateAfterBreakpoint()
>> +{
>> + // PC points one byte past the int3 responsible for the breakpoint.
>> + lldb::addr_t pc;
>> +
>> + if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
>> + return false;
>> +
>> + SetPC(pc - 1);
>> + return true;
>> +}
>> +
>> +uint32_t
>> +RegisterContext_x86_64::ConvertRegisterKindToRegisterNumber(uint32_t kind,
>> + uint32_t num)
>> +{
>> + if (kind == eRegisterKindGeneric)
>> + {
>> + switch (num)
>> + {
>> + case LLDB_REGNUM_GENERIC_PC: return gpr_rip;
>> + case LLDB_REGNUM_GENERIC_SP: return gpr_rsp;
>> + case LLDB_REGNUM_GENERIC_FP: return gpr_rbp;
>> + case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
>> + case LLDB_REGNUM_GENERIC_RA:
>> + default:
>> + return LLDB_INVALID_REGNUM;
>> + }
>> + }
>> +
>> + if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
>> + {
>> + switch (num)
>> + {
>> + case gcc_dwarf_gpr_rax: return gpr_rax;
>> + case gcc_dwarf_gpr_rdx: return gpr_rdx;
>> + case gcc_dwarf_gpr_rcx: return gpr_rcx;
>> + case gcc_dwarf_gpr_rbx: return gpr_rbx;
>> + case gcc_dwarf_gpr_rsi: return gpr_rsi;
>> + case gcc_dwarf_gpr_rdi: return gpr_rdi;
>> + case gcc_dwarf_gpr_rbp: return gpr_rbp;
>> + case gcc_dwarf_gpr_rsp: return gpr_rsp;
>> + case gcc_dwarf_gpr_r8: return gpr_r8;
>> + case gcc_dwarf_gpr_r9: return gpr_r9;
>> + case gcc_dwarf_gpr_r10: return gpr_r10;
>> + case gcc_dwarf_gpr_r11: return gpr_r11;
>> + case gcc_dwarf_gpr_r12: return gpr_r12;
>> + case gcc_dwarf_gpr_r13: return gpr_r13;
>> + case gcc_dwarf_gpr_r14: return gpr_r14;
>> + case gcc_dwarf_gpr_r15: return gpr_r15;
>> + case gcc_dwarf_gpr_rip: return gpr_rip;
>> + case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
>> + case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
>> + case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
>> + case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
>> + case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
>> + case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
>> + case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
>> + case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
>> + case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
>> + case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
>> + case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
>> + case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
>> + case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
>> + case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
>> + case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
>> + case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
>> + case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
>> + case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
>> + case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
>> + case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
>> + case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
>> + case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
>> + case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
>> + case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
>> + default:
>> + return LLDB_INVALID_REGNUM;
>> + }
>> + }
>> +
>> + if (kind == eRegisterKindGDB)
>> + {
>> + switch (num)
>> + {
>> + case gdb_gpr_rax : return gpr_rax;
>> + case gdb_gpr_rbx : return gpr_rbx;
>> + case gdb_gpr_rcx : return gpr_rcx;
>> + case gdb_gpr_rdx : return gpr_rdx;
>> + case gdb_gpr_rsi : return gpr_rsi;
>> + case gdb_gpr_rdi : return gpr_rdi;
>> + case gdb_gpr_rbp : return gpr_rbp;
>> + case gdb_gpr_rsp : return gpr_rsp;
>> + case gdb_gpr_r8 : return gpr_r8;
>> + case gdb_gpr_r9 : return gpr_r9;
>> + case gdb_gpr_r10 : return gpr_r10;
>> + case gdb_gpr_r11 : return gpr_r11;
>> + case gdb_gpr_r12 : return gpr_r12;
>> + case gdb_gpr_r13 : return gpr_r13;
>> + case gdb_gpr_r14 : return gpr_r14;
>> + case gdb_gpr_r15 : return gpr_r15;
>> + case gdb_gpr_rip : return gpr_rip;
>> + case gdb_gpr_rflags : return gpr_rflags;
>> + case gdb_gpr_cs : return gpr_cs;
>> + case gdb_gpr_ss : return gpr_ss;
>> + case gdb_gpr_ds : return gpr_ds;
>> + case gdb_gpr_es : return gpr_es;
>> + case gdb_gpr_fs : return gpr_fs;
>> + case gdb_gpr_gs : return gpr_gs;
>> + case gdb_fpu_stmm0 : return fpu_stmm0;
>> + case gdb_fpu_stmm1 : return fpu_stmm1;
>> + case gdb_fpu_stmm2 : return fpu_stmm2;
>> + case gdb_fpu_stmm3 : return fpu_stmm3;
>> + case gdb_fpu_stmm4 : return fpu_stmm4;
>> + case gdb_fpu_stmm5 : return fpu_stmm5;
>> + case gdb_fpu_stmm6 : return fpu_stmm6;
>> + case gdb_fpu_stmm7 : return fpu_stmm7;
>> + case gdb_fpu_fcw : return fpu_fcw;
>> + case gdb_fpu_fsw : return fpu_fsw;
>> + case gdb_fpu_ftw : return fpu_ftw;
>> + case gdb_fpu_cs : return fpu_cs;
>> + case gdb_fpu_ip : return fpu_ip;
>> + case gdb_fpu_ds : return fpu_ds;
>> + case gdb_fpu_dp : return fpu_dp;
>> + case gdb_fpu_fop : return fpu_fop;
>> + case gdb_fpu_xmm0 : return fpu_xmm0;
>> + case gdb_fpu_xmm1 : return fpu_xmm1;
>> + case gdb_fpu_xmm2 : return fpu_xmm2;
>> + case gdb_fpu_xmm3 : return fpu_xmm3;
>> + case gdb_fpu_xmm4 : return fpu_xmm4;
>> + case gdb_fpu_xmm5 : return fpu_xmm5;
>> + case gdb_fpu_xmm6 : return fpu_xmm6;
>> + case gdb_fpu_xmm7 : return fpu_xmm7;
>> + case gdb_fpu_xmm8 : return fpu_xmm8;
>> + case gdb_fpu_xmm9 : return fpu_xmm9;
>> + case gdb_fpu_xmm10 : return fpu_xmm10;
>> + case gdb_fpu_xmm11 : return fpu_xmm11;
>> + case gdb_fpu_xmm12 : return fpu_xmm12;
>> + case gdb_fpu_xmm13 : return fpu_xmm13;
>> + case gdb_fpu_xmm14 : return fpu_xmm14;
>> + case gdb_fpu_xmm15 : return fpu_xmm15;
>> + case gdb_fpu_mxcsr : return fpu_mxcsr;
>> + default:
>> + return LLDB_INVALID_REGNUM;
>> + }
>> + }
>> + else if (kind == eRegisterKindLLDB)
>> + {
>> + return num;
>> + }
>> +
>> + return LLDB_INVALID_REGNUM;
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::HardwareSingleStep(bool enable)
>> +{
>> + enum { TRACE_BIT = 0x100 };
>> + uint64_t rflags;
>> +
>> + if ((rflags = ReadRegisterAsUnsigned(gpr_rflags, -1UL)) == -1UL)
>> + return false;
>> +
>> + if (enable)
>> + {
>> + if (rflags & TRACE_BIT)
>> + return true;
>> +
>> + rflags |= TRACE_BIT;
>> + }
>> + else
>> + {
>> + if (!(rflags & TRACE_BIT))
>> + return false;
>> +
>> + rflags &= ~TRACE_BIT;
>> + }
>> +
>> + return WriteRegisterFromUnsigned(gpr_rflags, rflags);
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::ReadGPR()
>> +{
>> + ProcessMonitor &monitor = GetMonitor();
>> + return monitor.ReadGPR(&user.regs);
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::ReadFPR()
>> +{
>> + ProcessMonitor &monitor = GetMonitor();
>> + return monitor.ReadFPR(&user.i387);
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::WriteGPR()
>> +{
>> + ProcessMonitor &monitor = GetMonitor();
>> + return monitor.WriteGPR(&user.regs);
>> +}
>> +
>> +bool
>> +RegisterContext_x86_64::WriteFPR()
>> +{
>> + ProcessMonitor &monitor = GetMonitor();
>> + return monitor.WriteFPR(&user.i387);
>> +}
>> Index: source/Plugins/Process/POSIX/ProcessPOSIXLog.h
>> ===================================================================
>> --- source/Plugins/Process/POSIX/ProcessPOSIXLog.h (revision 0)
>> +++ source/Plugins/Process/POSIX/ProcessPOSIXLog.h (revision 0)
>> @@ -0,0 +1,106 @@
>> +//===-- ProcessLinuxLog.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_ProcessLinuxLog_h_
>> +#define liblldb_ProcessLinuxLog_h_
>> +
>> +// C Includes
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +
>> +// Project includes
>> +#include "lldb/Core/Log.h"
>> +
>> +#define POSIX_LOG_VERBOSE (1u << 0)
>> +#define POSIX_LOG_PROCESS (1u << 1)
>> +#define POSIX_LOG_THREAD (1u << 2)
>> +#define POSIX_LOG_PACKETS (1u << 3)
>> +#define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
>> +#define POSIX_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes
>> +#define POSIX_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
>> +#define POSIX_LOG_BREAKPOINTS (1u << 7)
>> +#define POSIX_LOG_WATCHPOINTS (1u << 8)
>> +#define POSIX_LOG_STEP (1u << 9)
>> +#define POSIX_LOG_COMM (1u << 10)
>> +#define POSIX_LOG_ASYNC (1u << 11)
>> +#define POSIX_LOG_PTRACE (1u << 12)
>> +#define POSIX_LOG_REGISTERS (1u << 13)
>> +#define POSIX_LOG_ALL (UINT32_MAX)
>> +#define POSIX_LOG_DEFAULT POSIX_LOG_PACKETS
>> +
>> +// The size which determines "short memory reads/writes".
>> +#define POSIX_LOG_MEMORY_SHORT_BYTES (4 * sizeof(ptrdiff_t))
>> +
>> +class ProcessPOSIXLog
>> +{
>> + static int m_nestinglevel;
>> + static const char *m_pluginname;
>> +
>> +public:
>> + static void
>> + RegisterPluginName(const char *pluginName)
>> + {
>> + m_pluginname = pluginName;
>> + }
>> +
>> +
>> + static lldb::LogSP
>> + GetLogIfAllCategoriesSet(uint32_t mask = 0);
>> +
>> + static void
>> + DisableLog (lldb_private::Args &args, lldb_private::Stream *feedback_strm);
>> +
>> + static lldb::LogSP
>> + EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options,
>> + lldb_private::Args &args, lldb_private::Stream *feedback_strm);
>> +
>> + static void
>> + ListLogCategories (lldb_private::Stream *strm);
>> +
>> + static void
>> + LogIf (uint32_t mask, const char *format, ...);
>> +
>> + // The following functions can be used to enable the client to limit
>> + // logging to only the top level function calls. This is useful for
>> + // recursive functions. FIXME: not thread safe!
>> + // Example:
>> + // void NestingFunc() {
>> + // LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
>> + // if (log)
>> + // {
>> + // ProcessLinuxLog::IncNestLevel();
>> + // if (ProcessLinuxLog::AtTopNestLevel())
>> + // log->Print(msg);
>> + // }
>> + // NestingFunc();
>> + // if (log)
>> + // ProcessLinuxLog::DecNestLevel();
>> + // }
>> +
>> + static bool
>> + AtTopNestLevel()
>> + {
>> + return m_nestinglevel == 1;
>> + }
>> +
>> + static void
>> + IncNestLevel()
>> + {
>> + ++m_nestinglevel;
>> + }
>> +
>> + static void
>> + DecNestLevel()
>> + {
>> + --m_nestinglevel;
>> + assert(m_nestinglevel >= 0);
>> + }
>> +};
>> +
>> +#endif // liblldb_ProcessLinuxLog_h_
>> Index: source/Plugins/Process/POSIX/RegisterContext_x86_64.h
>> ===================================================================
>> --- source/Plugins/Process/POSIX/RegisterContext_x86_64.h (revision 0)
>> +++ source/Plugins/Process/POSIX/RegisterContext_x86_64.h (revision 0)
>> @@ -0,0 +1,143 @@
>> +//===-- RegisterContext_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 liblldb_RegisterContext_x86_64_H_
>> +#define liblldb_RegisterContext_x86_64_H_
>> +
>> +#include "lldb/Core/Log.h"
>> +#include "RegisterContextPOSIX.h"
>> +
>> +#ifdef __FreeBSD__
>> +#include "RegisterContextFreeBSD_x86_64.h"
>> +#endif
>> +
>> +#ifdef __linux__
>> +#include "RegisterContextLinux_x86_64.h"
>> +#endif
>> +
>> +class ProcessMonitor;
>> +
>> +class RegisterContext_x86_64
>> + : public RegisterContextPOSIX
>> +{
>> +public:
>> + RegisterContext_x86_64 (lldb_private::Thread &thread,
>> + uint32_t concrete_frame_idx);
>> +
>> + ~RegisterContext_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 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_RegisterContext_x86_64_H_
>> Index: source/Plugins/Process/POSIX/RegisterContextPOSIX.h
>> ===================================================================
>> --- source/Plugins/Process/POSIX/RegisterContextPOSIX.h (revision 0)
>> +++ source/Plugins/Process/POSIX/RegisterContextPOSIX.h (revision 0)
>> @@ -0,0 +1,40 @@
>> +//===-- RegisterContextPOSIX.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_RegisterContextPOSIX_H_
>> +#define liblldb_RegisterContextPOSIX_H_
>> +
>> +// C Includes
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +#include "lldb/Target/RegisterContext.h"
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class RegisterContextPOSIX
>> +///
>> +/// @brief Extends RegisterClass with a few virtual operations useful on POSIX.
>> +class RegisterContextPOSIX
>> + : public lldb_private::RegisterContext
>> +{
>> +public:
>> + RegisterContextPOSIX(lldb_private::Thread &thread,
>> + uint32_t concrete_frame_idx)
>> + : RegisterContext(thread, concrete_frame_idx) { }
>> +
>> + /// Updates the register state of the associated thread after hitting a
>> + /// breakpoint (if that make sense for the architecture). Default
>> + /// implementation simply returns true for architectures which do not
>> + /// require any update.
>> + ///
>> + /// @return
>> + /// True if the operation succeeded and false otherwise.
>> + virtual bool UpdateAfterBreakpoint() { return true; }
>> +};
>> +
>> +#endif // #ifndef liblldb_RegisterContextPOSIX_H_
>> Index: source/Plugins/Process/POSIX/ProcessMessage.cpp
>> ===================================================================
>> --- source/Plugins/Process/POSIX/ProcessMessage.cpp (revision 0)
>> +++ source/Plugins/Process/POSIX/ProcessMessage.cpp (revision 0)
>> @@ -0,0 +1,245 @@
>> +//===-- ProcessMessage.cpp --------------------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +#include "ProcessMessage.h"
>> +
>> +using namespace lldb_private;
>> +
>> +const char *
>> +ProcessMessage::GetCrashReasonString(CrashReason reason)
>> +{
>> + const char *str = NULL;
>> +
>> + switch (reason)
>> + {
>> + default:
>> + assert(false && "invalid CrashReason");
>> + break;
>> +
>> + case eInvalidAddress:
>> + str = "invalid address";
>> + break;
>> + case ePrivilegedAddress:
>> + str = "address access protected";
>> + break;
>> + case eIllegalOpcode:
>> + str = "illegal instruction";
>> + break;
>> + case eIllegalOperand:
>> + str = "illegal instruction operand";
>> + break;
>> + case eIllegalAddressingMode:
>> + str = "illegal addressing mode";
>> + break;
>> + case eIllegalTrap:
>> + str = "illegal trap";
>> + break;
>> + case ePrivilegedOpcode:
>> + str = "privileged instruction";
>> + break;
>> + case ePrivilegedRegister:
>> + str = "privileged register";
>> + break;
>> + case eCoprocessorError:
>> + str = "coprocessor error";
>> + break;
>> + case eInternalStackError:
>> + str = "internal stack error";
>> + break;
>> + case eIllegalAlignment:
>> + str = "illegal alignment";
>> + break;
>> + case eIllegalAddress:
>> + str = "illegal address";
>> + break;
>> + case eHardwareError:
>> + str = "hardware error";
>> + break;
>> + case eIntegerDivideByZero:
>> + str = "integer divide by zero";
>> + break;
>> + case eIntegerOverflow:
>> + str = "integer overflow";
>> + break;
>> + case eFloatDivideByZero:
>> + str = "floating point divide by zero";
>> + break;
>> + case eFloatOverflow:
>> + str = "floating point overflow";
>> + break;
>> + case eFloatUnderflow:
>> + str = "floating point underflow";
>> + break;
>> + case eFloatInexactResult:
>> + str = "inexact floating point result";
>> + break;
>> + case eFloatInvalidOperation:
>> + str = "invalid floating point operation";
>> + break;
>> + case eFloatSubscriptRange:
>> + str = "invalid floating point subscript range";
>> + break;
>> + }
>> +
>> + return str;
>> +}
>> +
>> +const char *
>> +ProcessMessage::PrintCrashReason(CrashReason reason)
>> +{
>> +#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
>> + // Just return the code in asci for integration builds.
>> + chcar str[8];
>> + sprintf(str, "%d", reason);
>> +#else
>> + const char *str = NULL;
>> +
>> + switch (reason)
>> + {
>> + default:
>> + assert(false && "invalid CrashReason");
>> + break;
>> +
>> + case eInvalidCrashReason:
>> + str = "eInvalidCrashReason";
>> + break;
>> +
>> + // SIGSEGV crash reasons.
>> + case eInvalidAddress:
>> + str = "eInvalidAddress";
>> + break;
>> + case ePrivilegedAddress:
>> + str = "ePrivilegedAddress";
>> + break;
>> +
>> + // SIGILL crash reasons.
>> + case eIllegalOpcode:
>> + str = "eIllegalOpcode";
>> + break;
>> + case eIllegalOperand:
>> + str = "eIllegalOperand";
>> + break;
>> + case eIllegalAddressingMode:
>> + str = "eIllegalAddressingMode";
>> + break;
>> + case eIllegalTrap:
>> + str = "eIllegalTrap";
>> + break;
>> + case ePrivilegedOpcode:
>> + str = "ePrivilegedOpcode";
>> + break;
>> + case ePrivilegedRegister:
>> + str = "ePrivilegedRegister";
>> + break;
>> + case eCoprocessorError:
>> + str = "eCoprocessorError";
>> + break;
>> + case eInternalStackError:
>> + str = "eInternalStackError";
>> + break;
>> +
>> + // SIGBUS crash reasons:
>> + case eIllegalAlignment:
>> + str = "eIllegalAlignment";
>> + break;
>> + case eIllegalAddress:
>> + str = "eIllegalAddress";
>> + break;
>> + case eHardwareError:
>> + str = "eHardwareError";
>> + break;
>> +
>> + // SIGFPE crash reasons:
>> + case eIntegerDivideByZero:
>> + str = "eIntegerDivideByZero";
>> + break;
>> + case eIntegerOverflow:
>> + str = "eIntegerOverflow";
>> + break;
>> + case eFloatDivideByZero:
>> + str = "eFloatDivideByZero";
>> + break;
>> + case eFloatOverflow:
>> + str = "eFloatOverflow";
>> + break;
>> + case eFloatUnderflow:
>> + str = "eFloatUnderflow";
>> + break;
>> + case eFloatInexactResult:
>> + str = "eFloatInexactResult";
>> + break;
>> + case eFloatInvalidOperation:
>> + str = "eFloatInvalidOperation";
>> + break;
>> + case eFloatSubscriptRange:
>> + str = "eFloatSubscriptRange";
>> + break;
>> + }
>> +#endif
>> +
>> + return str;
>> +}
>> +
>> +const char *
>> +ProcessMessage::PrintCrashReason() const
>> +{
>> + return PrintCrashReason(m_crash_reason);
>> +}
>> +
>> +const char *
>> +ProcessMessage::PrintKind(Kind kind)
>> +{
>> +#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
>> + // Just return the code in asci for integration builds.
>> + chcar str[8];
>> + sprintf(str, "%d", reason);
>> +#else
>> + const char *str = NULL;
>> +
>> + switch (kind)
>> + {
>> + default:
>> + assert(false && "invalid Kind");
>> + break;
>> +
>> + case eInvalidMessage:
>> + str = "eInvalidMessage";
>> + break;
>> + case eExitMessage:
>> + str = "eExitMessage";
>> + break;
>> + case eLimboMessage:
>> + str = "eLimboMessage";
>> + break;
>> + case eSignalMessage:
>> + str = "eSignalMessage";
>> + break;
>> + case eSignalDeliveredMessage:
>> + str = "eSignalDeliveredMessage";
>> + break;
>> + case eTraceMessage:
>> + str = "eTraceMessage";
>> + break;
>> + case eBreakpointMessage:
>> + str = "eBreakpointMessage";
>> + break;
>> + case eCrashMessage:
>> + str = "eCrashMessage";
>> + break;
>> + }
>> +#endif
>> +
>> + return str;
>> +}
>> +
>> +const char *
>> +ProcessMessage::PrintKind() const
>> +{
>> + return PrintKind(m_kind);
>> +}
>> Index: source/Plugins/Process/POSIX/POSIXStopInfo.cpp
>> ===================================================================
>> --- source/Plugins/Process/POSIX/POSIXStopInfo.cpp (revision 0)
>> +++ source/Plugins/Process/POSIX/POSIXStopInfo.cpp (revision 0)
>> @@ -0,0 +1,60 @@
>> +//===-- POSIXStopInfo.cpp ---------------------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +#include "POSIXStopInfo.h"
>> +
>> +using namespace lldb;
>> +using namespace lldb_private;
>> +
>> +
>> +//===----------------------------------------------------------------------===//
>> +// POSIXLimboStopInfo
>> +
>> +POSIXLimboStopInfo::~POSIXLimboStopInfo() { }
>> +
>> +lldb::StopReason
>> +POSIXLimboStopInfo::GetStopReason() const
>> +{
>> + return lldb::eStopReasonTrace;
>> +}
>> +
>> +const char *
>> +POSIXLimboStopInfo::GetDescription()
>> +{
>> + return "thread exiting";
>> +}
>> +
>> +bool
>> +POSIXLimboStopInfo::ShouldStop(Event *event_ptr)
>> +{
>> + return true;
>> +}
>> +
>> +bool
>> +POSIXLimboStopInfo::ShouldNotify(Event *event_ptr)
>> +{
>> + return true;
>> +}
>> +
>> +//===----------------------------------------------------------------------===//
>> +// POSIXCrashStopInfo
>> +
>> +POSIXCrashStopInfo::~POSIXCrashStopInfo() { }
>> +
>> +lldb::StopReason
>> +POSIXCrashStopInfo::GetStopReason() const
>> +{
>> + return lldb::eStopReasonException;
>> +}
>> +
>> +const char *
>> +POSIXCrashStopInfo::GetDescription()
>> +{
>> + return ProcessMessage::GetCrashReasonString(m_crash_reason);
>> +}
>> Index: source/Plugins/Process/POSIX/ProcessMessage.h
>> ===================================================================
>> --- source/Plugins/Process/POSIX/ProcessMessage.h (revision 0)
>> +++ source/Plugins/Process/POSIX/ProcessMessage.h (revision 0)
>> @@ -0,0 +1,171 @@
>> +//===-- ProcessMessage.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_ProcessMessage_H_
>> +#define liblldb_ProcessMessage_H_
>> +
>> +#include <cassert>
>> +
>> +#include "lldb/lldb-defines.h"
>> +#include "lldb/lldb-types.h"
>> +
>> +class ProcessMessage
>> +{
>> +public:
>> +
>> + /// The type of signal this message can correspond to.
>> + enum Kind
>> + {
>> + eInvalidMessage,
>> + eExitMessage,
>> + eLimboMessage,
>> + eSignalMessage,
>> + eSignalDeliveredMessage,
>> + eTraceMessage,
>> + eBreakpointMessage,
>> + eCrashMessage
>> + };
>> +
>> + enum CrashReason
>> + {
>> + eInvalidCrashReason,
>> +
>> + // SIGSEGV crash reasons.
>> + eInvalidAddress,
>> + ePrivilegedAddress,
>> +
>> + // SIGILL crash reasons.
>> + eIllegalOpcode,
>> + eIllegalOperand,
>> + eIllegalAddressingMode,
>> + eIllegalTrap,
>> + ePrivilegedOpcode,
>> + ePrivilegedRegister,
>> + eCoprocessorError,
>> + eInternalStackError,
>> +
>> + // SIGBUS crash reasons,
>> + eIllegalAlignment,
>> + eIllegalAddress,
>> + eHardwareError,
>> +
>> + // SIGFPE crash reasons,
>> + eIntegerDivideByZero,
>> + eIntegerOverflow,
>> + eFloatDivideByZero,
>> + eFloatOverflow,
>> + eFloatUnderflow,
>> + eFloatInexactResult,
>> + eFloatInvalidOperation,
>> + eFloatSubscriptRange
>> + };
>> +
>> + ProcessMessage()
>> + : m_tid(LLDB_INVALID_PROCESS_ID),
>> + m_kind(eInvalidMessage),
>> + m_crash_reason(eInvalidCrashReason),
>> + m_status(0),
>> + m_addr(0) { }
>> +
>> + Kind GetKind() const { return m_kind; }
>> +
>> + lldb::tid_t GetTID() const { return m_tid; }
>> +
>> + /// Indicates that the thread @p tid is about to exit with status @p status.
>> + static ProcessMessage Limbo(lldb::tid_t tid, int status) {
>> + return ProcessMessage(tid, eLimboMessage, status);
>> + }
>> +
>> + /// Indicates that the thread @p tid had the signal @p signum delivered.
>> + static ProcessMessage Signal(lldb::tid_t tid, int signum) {
>> + return ProcessMessage(tid, eSignalMessage, signum);
>> + }
>> +
>> + /// Indicates that a signal @p signum generated by the debugging process was
>> + /// delivered to the thread @p tid.
>> + static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
>> + return ProcessMessage(tid, eSignalDeliveredMessage, signum);
>> + }
>> +
>> + /// Indicates that the thread @p tid encountered a trace point.
>> + static ProcessMessage Trace(lldb::tid_t tid) {
>> + return ProcessMessage(tid, eTraceMessage);
>> + }
>> +
>> + /// Indicates that the thread @p tid encountered a break point.
>> + static ProcessMessage Break(lldb::tid_t tid) {
>> + return ProcessMessage(tid, eBreakpointMessage);
>> + }
>> +
>> + /// Indicates that the thread @p tid crashed.
>> + static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason,
>> + int signo, lldb::addr_t fault_addr) {
>> + ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
>> + message.m_crash_reason = reason;
>> + return message;
>> + }
>> +
>> + int GetExitStatus() const {
>> + assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
>> + return m_status;
>> + }
>> +
>> + int GetSignal() const {
>> + assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
>> + GetKind() == eSignalDeliveredMessage);
>> + return m_status;
>> + }
>> +
>> + int GetStopStatus() const {
>> + assert(GetKind() == eSignalMessage);
>> + return m_status;
>> + }
>> +
>> + CrashReason GetCrashReason() const {
>> + assert(GetKind() == eCrashMessage);
>> + return m_crash_reason;
>> + }
>> +
>> + lldb::addr_t GetFaultAddress() const {
>> + assert(GetKind() == eCrashMessage);
>> + return m_addr;
>> + }
>> +
>> + static const char *
>> + GetCrashReasonString(CrashReason reason);
>> +
>> + const char *
>> + PrintCrashReason() const;
>> +
>> + static const char *
>> + PrintCrashReason(CrashReason reason);
>> +
>> + const char *
>> + PrintKind() const;
>> +
>> + static const char *
>> + PrintKind(Kind);
>> +
>> +private:
>> + ProcessMessage(lldb::tid_t tid, Kind kind,
>> + int status = 0, lldb::addr_t addr = 0)
>> + : m_tid(tid),
>> + m_kind(kind),
>> + m_crash_reason(eInvalidCrashReason),
>> + m_status(status),
>> + m_addr(addr) { }
>> +
>> + lldb::tid_t m_tid;
>> + Kind m_kind : 8;
>> + CrashReason m_crash_reason : 8;
>> + int m_status;
>> + lldb::addr_t m_addr;
>> +};
>> +
>> +#endif // #ifndef liblldb_ProcessMessage_H_
>> Index: source/Plugins/Process/POSIX/POSIXStopInfo.h
>> ===================================================================
>> --- source/Plugins/Process/POSIX/POSIXStopInfo.h (revision 0)
>> +++ source/Plugins/Process/POSIX/POSIXStopInfo.h (revision 0)
>> @@ -0,0 +1,92 @@
>> +//===-- POSIXStopInfo.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_POSIXStopInfo_H_
>> +#define liblldb_POSIXStopInfo_H_
>> +
>> +// C Includes
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +// Project includes
>> +#include "lldb/Target/StopInfo.h"
>> +
>> +#include "POSIXThread.h"
>> +#include "ProcessMessage.h"
>> +
>> +//===----------------------------------------------------------------------===//
>> +/// @class POSIXStopInfo
>> +/// @brief Simple base class for all POSIX-specific StopInfo objects.
>> +///
>> +class POSIXStopInfo
>> + : public lldb_private::StopInfo
>> +{
>> +public:
>> + POSIXStopInfo(lldb_private::Thread &thread, uint32_t status)
>> + : StopInfo(thread, status)
>> + { }
>> +};
>> +
>> +//===----------------------------------------------------------------------===//
>> +/// @class POSIXLimboStopInfo
>> +/// @brief Represents the stop state of a process ready to exit.
>> +///
>> +class POSIXLimboStopInfo
>> + : public POSIXStopInfo
>> +{
>> +public:
>> + POSIXLimboStopInfo(POSIXThread &thread)
>> + : POSIXStopInfo(thread, 0)
>> + { }
>> +
>> + ~POSIXLimboStopInfo();
>> +
>> + lldb::StopReason
>> + GetStopReason() const;
>> +
>> + const char *
>> + GetDescription();
>> +
>> + bool
>> + ShouldStop(lldb_private::Event *event_ptr);
>> +
>> + bool
>> + ShouldNotify(lldb_private::Event *event_ptr);
>> +};
>> +
>> +
>> +//===----------------------------------------------------------------------===//
>> +/// @class POSIXCrashStopInfo
>> +/// @brief Represents the stop state of process that is ready to crash.
>> +///
>> +class POSIXCrashStopInfo
>> + : public POSIXStopInfo
>> +{
>> +public:
>> + POSIXCrashStopInfo(POSIXThread &thread, uint32_t status,
>> + ProcessMessage::CrashReason reason)
>> + : POSIXStopInfo(thread, status),
>> + m_crash_reason(reason)
>> + { }
>> +
>> + ~POSIXCrashStopInfo();
>> +
>> + lldb::StopReason
>> + GetStopReason() const;
>> +
>> + const char *
>> + GetDescription();
>> +
>> + ProcessMessage::CrashReason
>> + GetCrashReason() const;
>> +
>> +private:
>> + ProcessMessage::CrashReason m_crash_reason;
>> +};
>> +
>> +#endif
>> Index: source/Plugins/Process/POSIX/POSIXThread.cpp
>> ===================================================================
>> --- source/Plugins/Process/POSIX/POSIXThread.cpp (revision 0)
>> +++ source/Plugins/Process/POSIX/POSIXThread.cpp (revision 0)
>> @@ -0,0 +1,352 @@
>> +//===-- POSIXThread.cpp -----------------------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +// C Includes
>> +#include <errno.h>
>> +
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +// Project includes
>> +#include "lldb/Core/Debugger.h"
>> +#include "lldb/Host/Host.h"
>> +#include "lldb/Target/Process.h"
>> +#include "lldb/Target/StopInfo.h"
>> +#include "lldb/Target/Target.h"
>> +#include "POSIXStopInfo.h"
>> +#include "POSIXThread.h"
>> +#include "ProcessPOSIX.h"
>> +#include "ProcessPOSIXLog.h"
>> +#include "ProcessMonitor.h"
>> +#include "RegisterContext_i386.h"
>> +#include "RegisterContext_x86_64.h"
>> +#include "RegisterContextPOSIX.h"
>> +
>> +#include "UnwindLLDB.h"
>> +
>> +using namespace lldb_private;
>> +
>> +
>> +POSIXThread::POSIXThread(Process &process, lldb::tid_t tid)
>> + : Thread(process, tid),
>> + m_frame_ap(0)
>> +{
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
>> + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
>> + log->Printf ("POSIXThread::%s (tid = %i)", __FUNCTION__, tid);
>> +}
>> +
>> +POSIXThread::~POSIXThread()
>> +{
>> + DestroyThread();
>> +}
>> +
>> +ProcessMonitor &
>> +POSIXThread::GetMonitor()
>> +{
>> + ProcessPOSIX &process = static_cast<ProcessPOSIX&>(GetProcess());
>> + return process.GetMonitor();
>> +}
>> +
>> +void
>> +POSIXThread::RefreshStateAfterStop()
>> +{
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
>> + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
>> + log->Printf ("POSIXThread::%s ()", __FUNCTION__);
>> +
>> + // Let all threads recover from stopping and do any clean up based
>> + // on the previous thread state (if any).
>> + ProcessPOSIX &process = static_cast<ProcessPOSIX&>(GetProcess());
>> + process.GetThreadList().RefreshStateAfterStop();
>> +}
>> +
>> +const char *
>> +POSIXThread::GetInfo()
>> +{
>> + return NULL;
>> +}
>> +
>> +lldb::RegisterContextSP
>> +POSIXThread::GetRegisterContext()
>> +{
>> + if (!m_reg_context_sp)
>> + {
>> + ArchSpec arch = Host::GetArchitecture();
>> +
>> + switch (arch.GetCore())
>> + {
>> + default:
>> + assert(false && "CPU type not supported!");
>> + break;
>> +
>> + case ArchSpec::eCore_x86_32_i386:
>> + case ArchSpec::eCore_x86_32_i486:
>> + case ArchSpec::eCore_x86_32_i486sx:
>> + m_reg_context_sp.reset(new RegisterContext_i386(*this, 0));
>> + break;
>> +
>> + case ArchSpec::eCore_x86_64_x86_64:
>> + m_reg_context_sp.reset(new RegisterContext_x86_64(*this, 0));
>> + break;
>> + }
>> + }
>> + return m_reg_context_sp;
>> +}
>> +
>> +lldb::RegisterContextSP
>> +POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
>> +{
>> + lldb::RegisterContextSP reg_ctx_sp;
>> + uint32_t concrete_frame_idx = 0;
>> +
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
>> + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
>> + log->Printf ("POSIXThread::%s ()", __FUNCTION__);
>> +
>> + if (frame)
>> + concrete_frame_idx = frame->GetConcreteFrameIndex();
>> +
>> + if (concrete_frame_idx == 0)
>> + reg_ctx_sp = GetRegisterContext();
>> + else
>> + {
>> + assert(GetUnwinder());
>> + reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
>> + }
>> +
>> + return reg_ctx_sp;
>> +}
>> +
>> +lldb::StopInfoSP
>> +POSIXThread::GetPrivateStopReason()
>> +{
>> + return m_stop_info;
>> +}
>> +
>> +Unwind *
>> +POSIXThread::GetUnwinder()
>> +{
>> + if (m_unwinder_ap.get() == NULL)
>> + m_unwinder_ap.reset(new UnwindLLDB(*this));
>> +
>> + return m_unwinder_ap.get();
>> +}
>> +
>> +bool
>> +POSIXThread::WillResume(lldb::StateType resume_state)
>> +{
>> + SetResumeState(resume_state);
>> +
>> + ClearStackFrames();
>> + if (m_unwinder_ap.get())
>> + m_unwinder_ap->Clear();
>> +
>> + return Thread::WillResume(resume_state);
>> +}
>> +
>> +bool
>> +POSIXThread::Resume()
>> +{
>> + lldb::StateType resume_state = GetResumeState();
>> + ProcessMonitor &monitor = GetMonitor();
>> + bool status;
>> +
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
>> + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
>> + log->Printf ("POSIXThread::%s ()", __FUNCTION__);
>> +
>> + switch (resume_state)
>> + {
>> + default:
>> + assert(false && "Unexpected state for resume!");
>> + status = false;
>> + break;
>> +
>> + case lldb::eStateRunning:
>> + SetState(resume_state);
>> + status = monitor.Resume(GetID(), GetResumeSignal());
>> + break;
>> +
>> + case lldb::eStateStepping:
>> + SetState(resume_state);
>> + status = monitor.SingleStep(GetID(), GetResumeSignal());
>> + break;
>> + }
>> +
>> + return status;
>> +}
>> +
>> +void
>> +POSIXThread::Notify(const ProcessMessage &message)
>> +{
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
>> + if (log)
>> + log->Printf ("POSIXThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind());
>> +
>> + switch (message.GetKind())
>> + {
>> + default:
>> + assert(false && "Unexpected message kind!");
>> + break;
>> +
>> + case ProcessMessage::eLimboMessage:
>> + LimboNotify(message);
>> + break;
>> +
>> + case ProcessMessage::eSignalMessage:
>> + SignalNotify(message);
>> + break;
>> +
>> + case ProcessMessage::eSignalDeliveredMessage:
>> + SignalDeliveredNotify(message);
>> + break;
>> +
>> + case ProcessMessage::eTraceMessage:
>> + TraceNotify(message);
>> + break;
>> +
>> + case ProcessMessage::eBreakpointMessage:
>> + BreakNotify(message);
>> + break;
>> +
>> + case ProcessMessage::eCrashMessage:
>> + CrashNotify(message);
>> + break;
>> + }
>> +}
>> +
>> +void
>> +POSIXThread::BreakNotify(const ProcessMessage &message)
>> +{
>> + bool status;
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
>> +
>> + assert(GetRegisterContext());
>> + status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint();
>> + assert(status && "Breakpoint update failed!");
>> +
>> + // With our register state restored, resolve the breakpoint object
>> + // corresponding to our current PC.
>> + assert(GetRegisterContext());
>> + lldb::addr_t pc = GetRegisterContext()->GetPC();
>> + if (log)
>> + log->Printf ("POSIXThread::%s () PC=0x%8.8llx", __FUNCTION__, pc);
>> + lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc));
>> + assert(bp_site);
>> + lldb::break_id_t bp_id = bp_site->GetID();
>> + assert(bp_site && bp_site->ValidForThisThread(this));
>> +
>> +
>> + m_breakpoint = bp_site;
>> + m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id);
>> +}
>> +
>> +void
>> +POSIXThread::TraceNotify(const ProcessMessage &message)
>> +{
>> + m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
>> +}
>> +
>> +void
>> +POSIXThread::LimboNotify(const ProcessMessage &message)
>> +{
>> + m_stop_info = lldb::StopInfoSP(new POSIXLimboStopInfo(*this));
>> +}
>> +
>> +void
>> +POSIXThread::SignalNotify(const ProcessMessage &message)
>> +{
>> + int signo = message.GetSignal();
>> +
>> + m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
>> + SetResumeSignal(signo);
>> +}
>> +
>> +void
>> +POSIXThread::SignalDeliveredNotify(const ProcessMessage &message)
>> +{
>> + int signo = message.GetSignal();
>> +
>> + // Just treat debugger generated signal events like breakpoints for now.
>> + m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
>> + SetResumeSignal(signo);
>> +}
>> +
>> +void
>> +POSIXThread::CrashNotify(const ProcessMessage &message)
>> +{
>> + int signo = message.GetSignal();
>> +
>> + assert(message.GetKind() == ProcessMessage::eCrashMessage);
>> +
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
>> + if (log)
>> + log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason());
>> +
>> + m_stop_info = lldb::StopInfoSP(new POSIXCrashStopInfo(
>> + *this, signo, message.GetCrashReason()));
>> + SetResumeSignal(signo);
>> +}
>> +
>> +unsigned
>> +POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
>> +{
>> + unsigned reg;
>> + ArchSpec arch = Host::GetArchitecture();
>> +
>> + switch (arch.GetCore())
>> + {
>> + default:
>> + assert(false && "CPU type not supported!");
>> + break;
>> +
>> + case ArchSpec::eCore_x86_32_i386:
>> + case ArchSpec::eCore_x86_32_i486:
>> + case ArchSpec::eCore_x86_32_i486sx:
>> + reg = RegisterContext_i386::GetRegisterIndexFromOffset(offset);
>> + break;
>> +
>> + case ArchSpec::eCore_x86_64_x86_64:
>> + reg = RegisterContext_x86_64::GetRegisterIndexFromOffset(offset);
>> + break;
>> + }
>> + return reg;
>> +}
>> +
>> +const char *
>> +POSIXThread::GetRegisterName(unsigned reg)
>> +{
>> + const char * name;
>> + ArchSpec arch = Host::GetArchitecture();
>> +
>> + switch (arch.GetCore())
>> + {
>> + default:
>> + assert(false && "CPU type not supported!");
>> + break;
>> +
>> + case ArchSpec::eCore_x86_32_i386:
>> + case ArchSpec::eCore_x86_32_i486:
>> + case ArchSpec::eCore_x86_32_i486sx:
>> + name = RegisterContext_i386::GetRegisterName(reg);
>> + break;
>> +
>> + case ArchSpec::eCore_x86_64_x86_64:
>> + name = RegisterContext_x86_64::GetRegisterName(reg);
>> + break;
>> + }
>> + return name;
>> +}
>> +
>> +const char *
>> +POSIXThread::GetRegisterNameFromOffset(unsigned offset)
>> +{
>> + return GetRegisterName(GetRegisterIndexFromOffset(offset));
>> +}
>> +
>> Index: source/Plugins/Process/POSIX/Makefile
>> ===================================================================
>> --- source/Plugins/Process/POSIX/Makefile (revision 0)
>> +++ source/Plugins/Process/POSIX/Makefile (revision 0)
>> @@ -0,0 +1,28 @@
>> +##===- source/Plugins/Process/POSIX/Makefile ---------------*- Makefile -*-===##
>> +#
>> +# The LLVM Compiler Infrastructure
>> +#
>> +# This file is distributed under the University of Illinois Open Source
>> +# License. See LICENSE.TXT for details.
>> +#
>> +##===----------------------------------------------------------------------===##
>> +
>> +LLDB_LEVEL := ../../../..
>> +LIBRARYNAME := lldbPluginProcessPOSIX
>> +BUILD_ARCHIVE = 1
>> +
>> +include $(LLDB_LEVEL)/../../Makefile.config
>> +
>> +# Extend the include path so we may locate UnwindLLDB.h
>> +CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility
>> +
>> +ifeq ($(HOST_OS),Linux)
>> +CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/Linux
>> +endif
>> +
>> +ifeq ($(HOST_OS),FreeBSD)
>> +# Extend the include path so we may locate ProcessMonitor
>> +CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/FreeBSD
>> +endif
>> +
>> +include $(LLDB_LEVEL)/Makefile
>> Index: source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
>> ===================================================================
>> --- source/Plugins/Process/FreeBSD/ProcessFreeBSD.h (revision 0)
>> +++ source/Plugins/Process/FreeBSD/ProcessFreeBSD.h (revision 0)
>> @@ -0,0 +1,84 @@
>> +//===-- ProcessFreeBSD.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_ProcessFreeBSD_H_
>> +#define liblldb_ProcessFreeBSD_H_
>> +
>> +// C Includes
>> +
>> +// C++ Includes
>> +#include <queue>
>> +
>> +// Other libraries and framework includes
>> +#include "lldb/Target/Process.h"
>> +#include "lldb/Target/ThreadList.h"
>> +#include "ProcessMessage.h"
>> +#include "ProcessPOSIX.h"
>> +
>> +class ProcessMonitor;
>> +
>> +class ProcessFreeBSD :
>> + public ProcessPOSIX
>> +{
>> +
>> +public:
>> + //------------------------------------------------------------------
>> + // Static functions.
>> + //------------------------------------------------------------------
>> + static Process*
>> + CreateInstance(lldb_private::Target& target,
>> + lldb_private::Listener &listener);
>> +
>> + static void
>> + Initialize();
>> +
>> + static void
>> + Terminate();
>> +
>> + static const char *
>> + GetPluginNameStatic();
>> +
>> + static const char *
>> + GetPluginDescriptionStatic();
>> +
>> + //------------------------------------------------------------------
>> + // Constructors and destructors
>> + //------------------------------------------------------------------
>> + ProcessFreeBSD(lldb_private::Target& target,
>> + lldb_private::Listener &listener);
>> +
>> + virtual uint32_t
>> + UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list);
>> +
>> + //------------------------------------------------------------------
>> + // PluginInterface protocol
>> + //------------------------------------------------------------------
>> + virtual const char *
>> + GetPluginName();
>> +
>> + virtual const char *
>> + GetShortPluginName();
>> +
>> + virtual uint32_t
>> + GetPluginVersion();
>> +
>> + virtual void
>> + GetPluginCommandHelp(const char *command, lldb_private::Stream *strm);
>> +
>> + virtual lldb_private::Error
>> + ExecutePluginCommand(lldb_private::Args &command,
>> + lldb_private::Stream *strm);
>> +
>> + virtual lldb_private::Log *
>> + EnablePluginLogging(lldb_private::Stream *strm,
>> + lldb_private::Args &command);
>> +
>> +};
>> +
>> +#endif // liblldb_MacOSXProcess_H_
>> Index: source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
>> ===================================================================
>> --- source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (revision 0)
>> +++ source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (revision 0)
>> @@ -0,0 +1,1558 @@
>> +//===-- ProcessMonitor.cpp ------------------------------------ -*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +// C Includes
>> +#include <errno.h>
>> +#include <poll.h>
>> +#include <string.h>
>> +#include <unistd.h>
>> +#include <signal.h>
>> +#include <sys/ptrace.h>
>> +#include <sys/socket.h>
>> +#include <sys/types.h>
>> +#include <sys/wait.h>
>> +
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +#include "lldb/Core/Error.h"
>> +#include "lldb/Core/RegisterValue.h"
>> +#include "lldb/Core/Scalar.h"
>> +#include "lldb/Host/Host.h"
>> +#include "lldb/Target/Thread.h"
>> +#include "lldb/Target/RegisterContext.h"
>> +#include "lldb/Utility/PseudoTerminal.h"
>> +
>> +
>> +#include "POSIXThread.h"
>> +#include "ProcessFreeBSD.h"
>> +#include "ProcessPOSIXLog.h"
>> +#include "ProcessMonitor.h"
>> +
>> +extern "C" {
>> + extern char ** environ;
>> + }
>> +
>> +using namespace lldb;
>> +using namespace lldb_private;
>> +
>> +// We disable the tracing of ptrace calls for integration builds to
>> +// avoid the additional indirection and checks.
>> +#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
>> +// Wrapper for ptrace to catch errors and log calls.
>> +
>> +const char *
>> +Get_PT_IO_OP(int op)
>> +{
>> + switch (op) {
>> + case PIOD_READ_D: return "READ_D";
>> + case PIOD_WRITE_D: return "WRITE_D";
>> + case PIOD_READ_I: return "READ_I";
>> + case PIOD_WRITE_I: return "WRITE_I";
>> + default: return "Unknown op";
>> + }
>> +}
>> +
>> +extern long
>> +PtraceWrapper(int req, ::pid_t pid, void *addr, int data,
>> + const char* reqName, const char* file, int line)
>> +{
>> + long int result;
>> +
>> + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
>> +
>> + if (log) {
>> + log->Printf("ptrace(%s, %u, %p, %x) called from file %s line %d",
>> + reqName, pid, addr, data, file, line);
>> + if (req == PT_IO) {
>> + struct ptrace_io_desc *pi = (struct ptrace_io_desc *) addr;
>> +
>> + log->Printf("PT_IO: op=%s offs=%zx size=%ld",
>> + Get_PT_IO_OP(pi->piod_op), pi->piod_offs, pi->piod_len);
>> + }
>> + }
>> +
>> + //PtraceDisplayBytes(req, data);
>> +
>> + errno = 0;
>> + result = ptrace(req, pid, (caddr_t) addr, data);
>> +
>> + //PtraceDisplayBytes(req, data);
>> +
>> + if (log && (result == -1 || errno != 0))
>> + {
>> + const char* str;
>> + switch (errno)
>> + {
>> + case ESRCH: str = "ESRCH"; break;
>> + case EINVAL: str = "EINVAL"; break;
>> + case EBUSY: str = "EBUSY"; break;
>> + case EPERM: str = "EPERM"; break;
>> + default: str = "<unknown>";
>> + }
>> + log->Printf("ptrace() failed; errno=%d (%s)", errno, str);
>> + }
>> +
>> + if (log) {
>> + if (req == PT_GETREGS) {
>> + struct reg *r = (struct reg *) addr;
>> +
>> + log->Printf("PT_GETREGS: ip=0x%lx", r->r_rip);
>> + log->Printf("PT_GETREGS: sp=0x%lx", r->r_rsp);
>> + log->Printf("PT_GETREGS: bp=0x%lx", r->r_rbp);
>> + log->Printf("PT_GETREGS: ax=0x%lx", r->r_rax);
>> + }
>> + }
>> +
>> + return result;
>> +}
>> +
>> +#define PTRACE(req, pid, addr, data) \
>> + PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
>> +#else
>> +#define PTRACE ptrace
>> +#endif
>> +
>> +//------------------------------------------------------------------------------
>> +// Static implementations of ProcessMonitor::ReadMemory and
>> +// ProcessMonitor::WriteMemory. This enables mutual recursion between these
>> +// functions without needed to go thru the thread funnel.
>> +
>> +static size_t
>> +DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf, size_t size,
>> + Error &error)
>> +{
>> + struct ptrace_io_desc pi_desc;
>> +
>> + pi_desc.piod_op = PIOD_READ_D;
>> + pi_desc.piod_offs = (void *)vm_addr;
>> + pi_desc.piod_addr = buf;
>> + pi_desc.piod_len = size;
>> +
>> + if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
>> + error.SetErrorToErrno();
>> + return pi_desc.piod_len;
>> +}
>> +
>> +static size_t
>> +DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr, const void *buf,
>> + size_t size, Error &error)
>> +{
>> + struct ptrace_io_desc pi_desc;
>> +
>> + pi_desc.piod_op = PIOD_WRITE_D;
>> + pi_desc.piod_offs = (void *)vm_addr;
>> + pi_desc.piod_addr = (void *)buf;
>> + pi_desc.piod_len = size;
>> +
>> + if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
>> + error.SetErrorToErrno();
>> + return pi_desc.piod_len;
>> +}
>> +
>> +// Simple helper function to ensure flags are enabled on the given file
>> +// descriptor.
>> +static bool
>> +EnsureFDFlags(int fd, int flags, Error &error)
>> +{
>> + int status;
>> +
>> + if ((status = fcntl(fd, F_GETFL)) == -1)
>> + {
>> + error.SetErrorToErrno();
>> + return false;
>> + }
>> +
>> + if (fcntl(fd, F_SETFL, status | flags) == -1)
>> + {
>> + error.SetErrorToErrno();
>> + return false;
>> + }
>> +
>> + return true;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class Operation
>> +/// @brief Represents a ProcessMonitor operation.
>> +///
>> +/// Under FreeBSD, it is not possible to ptrace() from any other thread but the
>> +/// one that spawned or attached to the process from the start. Therefore, when
>> +/// a ProcessMonitor is asked to deliver or change the state of an inferior
>> +/// process the operation must be "funneled" to a specific thread to perform the
>> +/// task. The Operation class provides an abstract base for all services the
>> +/// ProcessMonitor must perform via the single virtual function Execute, thus
>> +/// encapsulating the code that needs to run in the privileged context.
>> +class Operation
>> +{
>> +public:
>> + virtual void Execute(ProcessMonitor *monitor) = 0;
>> +};
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class ReadOperation
>> +/// @brief Implements ProcessMonitor::ReadMemory.
>> +class ReadOperation : public Operation
>> +{
>> +public:
>> + ReadOperation(lldb::addr_t addr, void *buff, size_t size,
>> + Error &error, size_t &result)
>> + : m_addr(addr), m_buff(buff), m_size(size),
>> + m_error(error), m_result(result)
>> + { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + lldb::addr_t m_addr;
>> + void *m_buff;
>> + size_t m_size;
>> + Error &m_error;
>> + size_t &m_result;
>> +};
>> +
>> +void
>> +ReadOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + lldb::pid_t pid = monitor->GetPID();
>> +
>> + m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error);
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class ReadOperation
>> +/// @brief Implements ProcessMonitor::WriteMemory.
>> +class WriteOperation : public Operation
>> +{
>> +public:
>> + WriteOperation(lldb::addr_t addr, const void *buff, size_t size,
>> + Error &error, size_t &result)
>> + : m_addr(addr), m_buff(buff), m_size(size),
>> + m_error(error), m_result(result)
>> + { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + lldb::addr_t m_addr;
>> + const void *m_buff;
>> + size_t m_size;
>> + Error &m_error;
>> + size_t &m_result;
>> +};
>> +
>> +void
>> +WriteOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + lldb::pid_t pid = monitor->GetPID();
>> +
>> + m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error);
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class ReadRegOperation
>> +/// @brief Implements ProcessMonitor::ReadRegisterValue.
>> +class ReadRegOperation : public Operation
>> +{
>> +public:
>> + ReadRegOperation(unsigned offset, unsigned size, RegisterValue &value, bool &result)
>> + : m_offset(offset), m_size(size), m_value(value), m_result(result)
>> + { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + unsigned m_offset;
>> + unsigned m_size;
>> + RegisterValue &m_value;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +ReadRegOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + lldb::pid_t pid = monitor->GetPID();
>> + struct reg regs;
>> + int rc;
>> +
>> + if ((rc = PTRACE(PT_GETREGS, pid, (caddr_t)®s, 0)) < 0) {
>> + m_result = false;
>> + } else {
>> + if (m_size == sizeof(uintptr_t))
>> + m_value = *(uintptr_t *)(((caddr_t)®s) + m_offset);
>> + else
>> + memcpy(&m_value, (((caddr_t)®s) + m_offset), m_size);
>> + m_result = true;
>> + }
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class WriteRegOperation
>> +/// @brief Implements ProcessMonitor::WriteRegisterValue.
>> +class WriteRegOperation : public Operation
>> +{
>> +public:
>> + WriteRegOperation(unsigned offset, const RegisterValue &value, bool &result)
>> + : m_offset(offset), m_value(value), m_result(result)
>> + { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + unsigned m_offset;
>> + const RegisterValue &m_value;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +WriteRegOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + lldb::pid_t pid = monitor->GetPID();
>> + struct reg regs;
>> +
>> + if (PTRACE(PT_GETREGS, pid, (caddr_t)®s, 0) < 0) {
>> + m_result = false;
>> + return;
>> + }
>> + *(uintptr_t *)(((caddr_t)®s) + m_offset) = (uintptr_t)m_value.GetAsUInt64();
>> + if (PTRACE(PT_SETREGS, pid, (caddr_t)®s, 0) < 0)
>> + m_result = false;
>> + else
>> + m_result = true;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class ReadGPROperation
>> +/// @brief Implements ProcessMonitor::ReadGPR.
>> +class ReadGPROperation : public Operation
>> +{
>> +public:
>> + ReadGPROperation(void *buf, bool &result)
>> + : m_buf(buf), m_result(result)
>> + { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + void *m_buf;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +ReadGPROperation::Execute(ProcessMonitor *monitor)
>> +{
>> + int rc;
>> +
>> + errno = 0;
>> + rc = PTRACE(PT_GETREGS, monitor->GetPID(), (caddr_t)m_buf, 0);
>> + if (errno != 0)
>> + m_result = false;
>> + else
>> + m_result = true;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class ReadFPROperation
>> +/// @brief Implements ProcessMonitor::ReadFPR.
>> +class ReadFPROperation : public Operation
>> +{
>> +public:
>> + ReadFPROperation(void *buf, bool &result)
>> + : m_buf(buf), m_result(result)
>> + { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + void *m_buf;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +ReadFPROperation::Execute(ProcessMonitor *monitor)
>> +{
>> + if (PTRACE(PT_GETFPREGS, monitor->GetPID(), (caddr_t)m_buf, 0) < 0)
>> + m_result = false;
>> + else
>> + m_result = true;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class WriteGPROperation
>> +/// @brief Implements ProcessMonitor::WriteGPR.
>> +class WriteGPROperation : public Operation
>> +{
>> +public:
>> + WriteGPROperation(void *buf, bool &result)
>> + : m_buf(buf), m_result(result)
>> + { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + void *m_buf;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +WriteGPROperation::Execute(ProcessMonitor *monitor)
>> +{
>> + if (PTRACE(PT_SETREGS, monitor->GetPID(), (caddr_t)m_buf, 0) < 0)
>> + m_result = false;
>> + else
>> + m_result = true;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class WriteFPROperation
>> +/// @brief Implements ProcessMonitor::WriteFPR.
>> +class WriteFPROperation : public Operation
>> +{
>> +public:
>> + WriteFPROperation(void *buf, bool &result)
>> + : m_buf(buf), m_result(result)
>> + { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + void *m_buf;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +WriteFPROperation::Execute(ProcessMonitor *monitor)
>> +{
>> + if (PTRACE(PT_SETFPREGS, monitor->GetPID(), (caddr_t)m_buf, 0) < 0)
>> + m_result = false;
>> + else
>> + m_result = true;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class ResumeOperation
>> +/// @brief Implements ProcessMonitor::Resume.
>> +class ResumeOperation : public Operation
>> +{
>> +public:
>> + ResumeOperation(lldb::tid_t tid, uint32_t signo, bool &result) :
>> + m_tid(tid), m_signo(signo), m_result(result) { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + lldb::tid_t m_tid;
>> + uint32_t m_signo;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +ResumeOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + int data = 0;
>> +
>> + if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
>> + data = m_signo;
>> +
>> + if (PTRACE(PT_CONTINUE, m_tid, (caddr_t)1, data))
>> + m_result = false;
>> + else
>> + m_result = true;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class ResumeOperation
>> +/// @brief Implements ProcessMonitor::SingleStep.
>> +class SingleStepOperation : public Operation
>> +{
>> +public:
>> + SingleStepOperation(lldb::tid_t tid, uint32_t signo, bool &result)
>> + : m_tid(tid), m_signo(signo), m_result(result) { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + lldb::tid_t m_tid;
>> + uint32_t m_signo;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +SingleStepOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + int data = 0;
>> +
>> + if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
>> + data = m_signo;
>> +
>> + if (PTRACE(PT_STEP, m_tid, NULL, data))
>> + m_result = false;
>> + else
>> + m_result = true;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class SiginfoOperation
>> +/// @brief Implements ProcessMonitor::GetSignalInfo.
>> +class SiginfoOperation : public Operation
>> +{
>> +public:
>> + SiginfoOperation(lldb::tid_t tid, void *info, bool &result)
>> + : m_tid(tid), m_info(info), m_result(result) { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + lldb::tid_t m_tid;
>> + void *m_info;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +SiginfoOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + struct ptrace_lwpinfo plwp;
>> +
>> + if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
>> + m_result = false;
>> + else {
>> + memcpy(m_info, &plwp.pl_siginfo, sizeof(siginfo_t));
>> + m_result = true;
>> + }
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class EventMessageOperation
>> +/// @brief Implements ProcessMonitor::GetEventMessage.
>> +class EventMessageOperation : public Operation
>> +{
>> +public:
>> + EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
>> + : m_tid(tid), m_message(message), m_result(result) { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + lldb::tid_t m_tid;
>> + unsigned long *m_message;
>> + bool &m_result;
>> +};
>> +
>> +void
>> +EventMessageOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + struct ptrace_lwpinfo plwp;
>> +
>> + if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
>> + m_result = false;
>> + else {
>> + if (plwp.pl_flags & PL_FLAG_FORKED) {
>> + m_message = (unsigned long *)plwp.pl_child_pid;
>> + m_result = true;
>> + } else
>> + m_result = false;
>> + }
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class KillOperation
>> +/// @brief Implements ProcessMonitor::BringProcessIntoLimbo.
>> +class KillOperation : public Operation
>> +{
>> +public:
>> + KillOperation(bool &result) : m_result(result) { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + bool &m_result;
>> +};
>> +
>> +void
>> +KillOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + lldb::pid_t pid = monitor->GetPID();
>> +
>> + if (PTRACE(PT_KILL, pid, NULL, 0))
>> + m_result = false;
>> + else
>> + m_result = true;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +/// @class KillOperation
>> +/// @brief Implements ProcessMonitor::BringProcessIntoLimbo.
>> +class DetachOperation : public Operation
>> +{
>> +public:
>> + DetachOperation(Error &result) : m_error(result) { }
>> +
>> + void Execute(ProcessMonitor *monitor);
>> +
>> +private:
>> + Error &m_error;
>> +};
>> +
>> +void
>> +DetachOperation::Execute(ProcessMonitor *monitor)
>> +{
>> + lldb::pid_t pid = monitor->GetPID();
>> +
>> + if (PTRACE(PT_DETACH, pid, NULL, 0) < 0)
>> + m_error.SetErrorToErrno();
>> +
>> +}
>> +
>> +ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor)
>> + : m_monitor(monitor)
>> +{
>> + sem_init(&m_semaphore, 0, 0);
>> +}
>> +
>> +ProcessMonitor::OperationArgs::~OperationArgs()
>> +{
>> + sem_destroy(&m_semaphore);
>> +}
>> +
>> +ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
>> + lldb_private::Module *module,
>> + char const **argv,
>> + char const **envp,
>> + const char *stdin_path,
>> + const char *stdout_path,
>> + const char *stderr_path)
>> + : OperationArgs(monitor),
>> + m_module(module),
>> + m_argv(argv),
>> + m_envp(envp),
>> + m_stdin_path(stdin_path),
>> + m_stdout_path(stdout_path),
>> + m_stderr_path(stderr_path) { }
>> +
>> +ProcessMonitor::LaunchArgs::~LaunchArgs()
>> +{ }
>> +
>> +ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor,
>> + lldb::pid_t pid)
>> + : OperationArgs(monitor), m_pid(pid) { }
>> +
>> +ProcessMonitor::AttachArgs::~AttachArgs()
>> +{ }
>> +
>> +//------------------------------------------------------------------------------
>> +/// The basic design of the ProcessMonitor is built around two threads.
>> +///
>> +/// One thread (@see SignalThread) simply blocks on a call to waitpid() looking
>> +/// for changes in the debugee state. When a change is detected a
>> +/// ProcessMessage is sent to the associated ProcessFreeBSD instance. This thread
>> +/// "drives" state changes in the debugger.
>> +///
>> +/// The second thread (@see OperationThread) is responsible for two things 1)
>> +/// 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(ProcessPOSIX *process,
>> + Module *module,
>> + const char *argv[],
>> + const char *envp[],
>> + const char *stdin_path,
>> + const char *stdout_path,
>> + const char *stderr_path,
>> + lldb_private::Error &error)
>> + : m_process(static_cast<ProcessFreeBSD *>(process)),
>> + m_operation_thread(LLDB_INVALID_HOST_THREAD),
>> + m_monitor_thread(LLDB_INVALID_HOST_THREAD),
>> + m_pid(LLDB_INVALID_PROCESS_ID),
>> + m_server_mutex(Mutex::eMutexTypeRecursive),
>> + m_terminal_fd(-1),
>> + m_client_fd(-1),
>> + m_server_fd(-1)
>> +{
>> + std::auto_ptr<LaunchArgs> args;
>> +
>> + args.reset(new LaunchArgs(this, module, argv, envp,
>> + stdin_path, stdout_path, stderr_path));
>> +
>> +
>> + // Server/client descriptors.
>> + if (!EnableIPC())
>> + {
>> + error.SetErrorToGenericError();
>> + error.SetErrorString("Monitor failed to initialize.");
>> + }
>> +
>> + StartLaunchOpThread(args.get(), error);
>> + if (!error.Success())
>> + return;
>> +
>> +WAIT_AGAIN:
>> + // Wait for the operation thread to initialize.
>> + if (sem_wait(&args->m_semaphore))
>> + {
>> + if (errno == EINTR)
>> + goto WAIT_AGAIN;
>> + else
>> + {
>> + error.SetErrorToErrno();
>> + return;
>> + }
>> + }
>> +
>> + // Check that the launch was a success.
>> + if (!args->m_error.Success())
>> + {
>> + StopLaunchOpThread();
>> + error = args->m_error;
>> + return;
>> + }
>> +
>> + // Finally, start monitoring the child process for change in state.
>> + m_monitor_thread = Host::StartMonitoringChildProcess(
>> + ProcessMonitor::MonitorCallback, this, GetPID(), true);
>> + if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread))
>> + {
>> + error.SetErrorToGenericError();
>> + error.SetErrorString("Process launch failed.");
>> + return;
>> + }
>> +}
>> +
>> +ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
>> + lldb::pid_t pid,
>> + lldb_private::Error &error)
>> + : m_process(static_cast<ProcessFreeBSD *>(process)),
>> + m_operation_thread(LLDB_INVALID_HOST_THREAD),
>> + m_monitor_thread(LLDB_INVALID_HOST_THREAD),
>> + m_pid(pid),
>> + m_server_mutex(Mutex::eMutexTypeRecursive),
>> + m_terminal_fd(-1),
>> + m_client_fd(-1),
>> + m_server_fd(-1)
>> +{
>> + std::auto_ptr<AttachArgs> args;
>> +
>> + args.reset(new AttachArgs(this, pid));
>> +
>> + // Server/client descriptors.
>> + if (!EnableIPC())
>> + {
>> + error.SetErrorToGenericError();
>> + error.SetErrorString("Monitor failed to initialize.");
>> + }
>> +
>> + StartAttachOpThread(args.get(), error);
>> + if (!error.Success())
>> + return;
>> +
>> +WAIT_AGAIN:
>> + // Wait for the operation thread to initialize.
>> + if (sem_wait(&args->m_semaphore))
>> + {
>> + if (errno == EINTR)
>> + goto WAIT_AGAIN;
>> + else
>> + {
>> + error.SetErrorToErrno();
>> + return;
>> + }
>> + }
>> +
>> + // Check that the launch was a success.
>> + if (!args->m_error.Success())
>> + {
>> + StopAttachOpThread();
>> + error = args->m_error;
>> + return;
>> + }
>> +
>> + // Finally, start monitoring the child process for change in state.
>> + m_monitor_thread = Host::StartMonitoringChildProcess(
>> + ProcessMonitor::MonitorCallback, this, GetPID(), true);
>> + if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread))
>> + {
>> + error.SetErrorToGenericError();
>> + error.SetErrorString("Process attach failed.");
>> + return;
>> + }
>> +}
>> +
>> +ProcessMonitor::~ProcessMonitor()
>> +{
>> + StopMonitor();
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +// Thread setup and tear down.
>> +void
>> +ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error)
>> +{
>> + static const char *g_thread_name = "lldb.process.freebsd.operation";
>> +
>> + if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
>> + return;
>> +
>> + m_operation_thread =
>> + Host::ThreadCreate(g_thread_name, LaunchOpThread, args, &error);
>> +}
>> +
>> +void
>> +ProcessMonitor::StopLaunchOpThread()
>> +{
>> + lldb::thread_result_t result;
>> +
>> + if (!IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
>> + return;
>> +
>> + Host::ThreadCancel(m_operation_thread, NULL);
>> + Host::ThreadJoin(m_operation_thread, &result, NULL);
>> +}
>> +
>> +void *
>> +ProcessMonitor::LaunchOpThread(void *arg)
>> +{
>> + LaunchArgs *args = static_cast<LaunchArgs*>(arg);
>> +
>> + if (!Launch(args)) {
>> + sem_post(&args->m_semaphore);
>> + return NULL;
>> + }
>> +
>> + ServeOperation(args);
>> + return NULL;
>> +}
>> +
>> +bool
>> +ProcessMonitor::Launch(LaunchArgs *args)
>> +{
>> + ProcessMonitor *monitor = args->m_monitor;
>> + ProcessFreeBSD &process = monitor->GetProcess();
>> + const char **argv = args->m_argv;
>> + const char **envp = args->m_envp;
>> + const char *stdin_path = args->m_stdin_path;
>> + const char *stdout_path = args->m_stdout_path;
>> + const char *stderr_path = args->m_stderr_path;
>> + lldb::pid_t pid;
>> +
>> + lldb::ThreadSP inferior;
>> +
>> + // Propagate the environment if one is not supplied.
>> + if (envp == NULL || envp[0] == NULL)
>> + envp = const_cast<const char **>(environ);
>> +
>> + // Recognized child exit status codes.
>> + enum {
>> + ePtraceFailed = 1,
>> + eDupStdinFailed,
>> + eDupStdoutFailed,
>> + eDupStderrFailed,
>> + eExecFailed
>> + };
>> +
>> + pid = fork();
>> +
>> + // Child process.
>> + if (pid == 0)
>> + {
>> + // Trace this process.
>> + if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
>> + exit(ePtraceFailed);
>> +
>> + // Do not inherit setgid powers.
>> + setgid(getgid());
>> +
>> + // Let us have our own process group.
>> + setpgid(0, 0);
>> +
>> + // Dup file descriptors if needed.
>> + //
>> + // FIXME: If two or more of the paths are the same we needlessly open
>> + // the same file multiple times.
>> + if (stdin_path != NULL && stdin_path[0])
>> + if (!DupDescriptor(stdin_path, STDIN_FILENO, O_RDONLY))
>> + exit(eDupStdinFailed);
>> +
>> + if (stdout_path != NULL && stdout_path[0])
>> + if (!DupDescriptor(stdout_path, STDOUT_FILENO, O_WRONLY | O_CREAT))
>> + exit(eDupStdoutFailed);
>> +
>> + if (stderr_path != NULL && stderr_path[0])
>> + if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))
>> + exit(eDupStderrFailed);
>> +
>> + // Execute. We should never return.
>> + execve(argv[0],
>> + const_cast<char *const *>(argv),
>> + const_cast<char *const *>(envp));
>> + exit(eExecFailed);
>> + }
>> +
>> + // Wait for the child process to to trap on its call to execve.
>> + ::pid_t wpid;
>> + int status;
>> + if ((wpid = waitpid(pid, &status, 0)) < 0)
>> + {
>> + args->m_error.SetErrorToErrno();
>> + goto FINISH;
>> + }
>> + else if (WIFEXITED(status))
>> + {
>> + // open, dup or execve likely failed for some reason.
>> + args->m_error.SetErrorToGenericError();
>> + switch (WEXITSTATUS(status))
>> + {
>> + case ePtraceFailed:
>> + args->m_error.SetErrorString("Child ptrace failed.");
>> + break;
>> + case eDupStdinFailed:
>> + args->m_error.SetErrorString("Child open stdin failed.");
>> + break;
>> + case eDupStdoutFailed:
>> + args->m_error.SetErrorString("Child open stdout failed.");
>> + break;
>> + case eDupStderrFailed:
>> + args->m_error.SetErrorString("Child open stderr failed.");
>> + break;
>> + case eExecFailed:
>> + args->m_error.SetErrorString("Child exec failed.");
>> + break;
>> + default:
>> + args->m_error.SetErrorString("Child returned unknown exit status.");
>> + break;
>> + }
>> + goto FINISH;
>> + }
>> + assert(WIFSTOPPED(status) && wpid == pid &&
>> + "Could not sync with inferior process.");
>> +
>> +#ifdef notyet
>> + // Have the child raise an event on exit. This is used to keep the child in
>> + // limbo until it is destroyed.
>> + if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEEXIT) < 0)
>> + {
>> + args->m_error.SetErrorToErrno();
>> + goto FINISH;
>> + }
>> +#endif
>> + // XXX - Release the master terminal descriptor and pass it off to the
>> + // XXX - ProcessMonitor instance. Similarly stash the inferior pid.
>> + // For now just use stdin fd
>> + monitor->m_terminal_fd = STDIN_FILENO;
>> + monitor->m_pid = pid;
>> +
>> + // Set the terminal fd to be in non blocking mode (it simplifies the
>> + // implementation of ProcessFreeBSD::GetSTDOUT to have a non-blocking
>> + // descriptor to read from).
>> + if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
>> + goto FINISH;
>> +
>> + // Update the process thread list with this new thread.
>> + inferior.reset(new POSIXThread(process, pid));
>> + process.GetThreadList().AddThread(inferior);
>> +
>> + // Let our process instance know the thread has stopped.
>> + process.SendMessage(ProcessMessage::Trace(pid));
>> +
>> +FINISH:
>> + return args->m_error.Success();
>> +}
>> +
>> +bool
>> +ProcessMonitor::EnableIPC()
>> +{
>> + int fd[2];
>> +
>> + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd))
>> + return false;
>> +
>> + m_client_fd = fd[0];
>> + m_server_fd = fd[1];
>> + return true;
>> +}
>> +
>> +void
>> +ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error)
>> +{
>> + static const char *g_thread_name = "lldb.process.freebsd.operation";
>> +
>> + if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
>> + return;
>> +
>> + m_operation_thread =
>> + Host::ThreadCreate(g_thread_name, AttachOpThread, args, &error);
>> +}
>> +
>> +void
>> +ProcessMonitor::StopAttachOpThread()
>> +{
>> + assert(!"Not implemented yet!!!");
>> +}
>> +
>> +void *
>> +ProcessMonitor::AttachOpThread(void *arg)
>> +{
>> + AttachArgs *args = static_cast<AttachArgs*>(arg);
>> +
>> + if (!Attach(args))
>> + return NULL;
>> +
>> + ServeOperation(args);
>> + return NULL;
>> +}
>> +
>> +bool
>> +ProcessMonitor::Attach(AttachArgs *args)
>> +{
>> + lldb::pid_t pid = args->m_pid;
>> +
>> + ProcessMonitor *monitor = args->m_monitor;
>> + ProcessFreeBSD &process = monitor->GetProcess();
>> + ThreadList &tl = process.GetThreadList();
>> + lldb::ThreadSP inferior;
>> +
>> + if (pid <= 1)
>> + {
>> + args->m_error.SetErrorToGenericError();
>> + args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
>> + goto FINISH;
>> + }
>> +
>> + // Attach to the requested process.
>> + if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0)
>> + {
>> + args->m_error.SetErrorToErrno();
>> + goto FINISH;
>> + }
>> +
>> + int status;
>> + if ((status = waitpid(pid, NULL, 0)) < 0)
>> + {
>> + args->m_error.SetErrorToErrno();
>> + goto FINISH;
>> + }
>> +
>> + // Update the process thread list with the attached thread.
>> + inferior.reset(new POSIXThread(process, pid));
>> + tl.AddThread(inferior);
>> +
>> + // Let our process instance know the thread has stopped.
>> + process.SendMessage(ProcessMessage::Trace(pid));
>> +
>> + FINISH:
>> + return args->m_error.Success();
>> +}
>> +
>> +bool
>> +ProcessMonitor::MonitorCallback(void *callback_baton,
>> + lldb::pid_t pid,
>> + bool exited,
>> + int signal,
>> + int status)
>> +{
>> + ProcessMessage message;
>> + ProcessMonitor *monitor = static_cast<ProcessMonitor*>(callback_baton);
>> + ProcessFreeBSD *process = monitor->m_process;
>> + bool stop_monitoring;
>> + siginfo_t info;
>> +
>> + if (!monitor->GetSignalInfo(pid, &info))
>> + stop_monitoring = true; // pid is gone. Bail.
>> + else {
>> + switch (info.si_signo)
>> + {
>> + case SIGTRAP:
>> + message = MonitorSIGTRAP(monitor, &info, pid);
>> + break;
>> +
>> + default:
>> + message = MonitorSignal(monitor, &info, pid);
>> + break;
>> + }
>> +
>> + process->SendMessage(message);
>> + stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
>> + }
>> +
>> + return stop_monitoring;
>> +}
>> +
>> +ProcessMessage
>> +ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
>> + const siginfo_t *info, lldb::pid_t pid)
>> +{
>> + ProcessMessage message;
>> +
>> + assert(info->si_signo == SIGTRAP && "Unexpected child signal!");
>> +
>> + switch (info->si_code)
>> + {
>> + default:
>> + assert(false && "Unexpected SIGTRAP code!");
>> + break;
>> +
>> + case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */):
>> + {
>> + // The inferior process is about to exit. Maintain the process in a
>> + // state of "limbo" until we are explicitly commanded to detach,
>> + // destroy, resume, etc.
>> + unsigned long data = 0;
>> + if (!monitor->GetEventMessage(pid, &data))
>> + data = -1;
>> + message = ProcessMessage::Limbo(pid, (data >> 8));
>> + break;
>> + }
>> +
>> + case 0:
>> + case TRAP_TRACE:
>> + message = ProcessMessage::Trace(pid);
>> + break;
>> +
>> + case SI_KERNEL:
>> + case TRAP_BRKPT:
>> + message = ProcessMessage::Break(pid);
>> + break;
>> + }
>> +
>> + return message;
>> +}
>> +
>> +ProcessMessage
>> +ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
>> + const siginfo_t *info, lldb::pid_t pid)
>> +{
>> + ProcessMessage message;
>> + int signo = info->si_signo;
>> +
>> + // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
>> + // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
>> + // kill(2) or raise(3). Similarly for tgkill(2) on FreeBSD.
>> + //
>> + // IOW, user generated signals never generate what we consider to be a
>> + // "crash".
>> + //
>> + // Similarly, ACK signals generated by this monitor.
>> + if (info->si_code == SI_USER)
>> + {
>> + if (info->si_pid == getpid())
>> + return ProcessMessage::SignalDelivered(pid, signo);
>> + else
>> + return ProcessMessage::Signal(pid, signo);
>> + }
>> +
>> + if (signo == SIGSEGV) {
>> + lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
>> + ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info);
>> + return ProcessMessage::Crash(pid, reason, signo, fault_addr);
>> + }
>> +
>> + if (signo == SIGILL) {
>> + lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
>> + ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info);
>> + return ProcessMessage::Crash(pid, reason, signo, fault_addr);
>> + }
>> +
>> + if (signo == SIGFPE) {
>> + lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
>> + ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info);
>> + return ProcessMessage::Crash(pid, reason, signo, fault_addr);
>> + }
>> +
>> + if (signo == SIGBUS) {
>> + lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
>> + ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info);
>> + return ProcessMessage::Crash(pid, reason, signo, fault_addr);
>> + }
>> +
>> + // Everything else is "normal" and does not require any special action on
>> + // our part.
>> + return ProcessMessage::Signal(pid, signo);
>> +}
>> +
>> +ProcessMessage::CrashReason
>> +ProcessMonitor::GetCrashReasonForSIGSEGV(const siginfo_t *info)
>> +{
>> + ProcessMessage::CrashReason reason;
>> + assert(info->si_signo == SIGSEGV);
>> +
>> + reason = ProcessMessage::eInvalidCrashReason;
>> +
>> + switch (info->si_code)
>> + {
>> + default:
>> + assert(false && "unexpected si_code for SIGSEGV");
>> + break;
>> + case SEGV_MAPERR:
>> + reason = ProcessMessage::eInvalidAddress;
>> + break;
>> + case SEGV_ACCERR:
>> + reason = ProcessMessage::ePrivilegedAddress;
>> + break;
>> + }
>> +
>> + return reason;
>> +}
>> +
>> +ProcessMessage::CrashReason
>> +ProcessMonitor::GetCrashReasonForSIGILL(const siginfo_t *info)
>> +{
>> + ProcessMessage::CrashReason reason;
>> + assert(info->si_signo == SIGILL);
>> +
>> + reason = ProcessMessage::eInvalidCrashReason;
>> +
>> + switch (info->si_code)
>> + {
>> + default:
>> + assert(false && "unexpected si_code for SIGILL");
>> + break;
>> + case ILL_ILLOPC:
>> + reason = ProcessMessage::eIllegalOpcode;
>> + break;
>> + case ILL_ILLOPN:
>> + reason = ProcessMessage::eIllegalOperand;
>> + break;
>> + case ILL_ILLADR:
>> + reason = ProcessMessage::eIllegalAddressingMode;
>> + break;
>> + case ILL_ILLTRP:
>> + reason = ProcessMessage::eIllegalTrap;
>> + break;
>> + case ILL_PRVOPC:
>> + reason = ProcessMessage::ePrivilegedOpcode;
>> + break;
>> + case ILL_PRVREG:
>> + reason = ProcessMessage::ePrivilegedRegister;
>> + break;
>> + case ILL_COPROC:
>> + reason = ProcessMessage::eCoprocessorError;
>> + break;
>> + case ILL_BADSTK:
>> + reason = ProcessMessage::eInternalStackError;
>> + break;
>> + }
>> +
>> + return reason;
>> +}
>> +
>> +ProcessMessage::CrashReason
>> +ProcessMonitor::GetCrashReasonForSIGFPE(const siginfo_t *info)
>> +{
>> + ProcessMessage::CrashReason reason;
>> + assert(info->si_signo == SIGFPE);
>> +
>> + reason = ProcessMessage::eInvalidCrashReason;
>> +
>> + switch (info->si_code)
>> + {
>> + default:
>> + assert(false && "unexpected si_code for SIGFPE");
>> + break;
>> + case FPE_INTDIV:
>> + reason = ProcessMessage::eIntegerDivideByZero;
>> + break;
>> + case FPE_INTOVF:
>> + reason = ProcessMessage::eIntegerOverflow;
>> + break;
>> + case FPE_FLTDIV:
>> + reason = ProcessMessage::eFloatDivideByZero;
>> + break;
>> + case FPE_FLTOVF:
>> + reason = ProcessMessage::eFloatOverflow;
>> + break;
>> + case FPE_FLTUND:
>> + reason = ProcessMessage::eFloatUnderflow;
>> + break;
>> + case FPE_FLTRES:
>> + reason = ProcessMessage::eFloatInexactResult;
>> + break;
>> + case FPE_FLTINV:
>> + reason = ProcessMessage::eFloatInvalidOperation;
>> + break;
>> + case FPE_FLTSUB:
>> + reason = ProcessMessage::eFloatSubscriptRange;
>> + break;
>> + }
>> +
>> + return reason;
>> +}
>> +
>> +ProcessMessage::CrashReason
>> +ProcessMonitor::GetCrashReasonForSIGBUS(const siginfo_t *info)
>> +{
>> + ProcessMessage::CrashReason reason;
>> + assert(info->si_signo == SIGBUS);
>> +
>> + reason = ProcessMessage::eInvalidCrashReason;
>> +
>> + switch (info->si_code)
>> + {
>> + default:
>> + assert(false && "unexpected si_code for SIGBUS");
>> + break;
>> + case BUS_ADRALN:
>> + reason = ProcessMessage::eIllegalAlignment;
>> + break;
>> + case BUS_ADRERR:
>> + reason = ProcessMessage::eIllegalAddress;
>> + break;
>> + case BUS_OBJERR:
>> + reason = ProcessMessage::eHardwareError;
>> + break;
>> + }
>> +
>> + return reason;
>> +}
>> +
>> +void
>> +ProcessMonitor::ServeOperation(OperationArgs *args)
>> +{
>> + int status;
>> + pollfd fdset;
>> +
>> + ProcessMonitor *monitor = args->m_monitor;
>> +
>> + fdset.fd = monitor->m_server_fd;
>> + fdset.events = POLLIN | POLLPRI;
>> + fdset.revents = 0;
>> +
>> + // We are finised with the arguments and are ready to go. Sync with the
>> + // parent thread and start serving operations on the inferior.
>> + sem_post(&args->m_semaphore);
>> +
>> + for (;;)
>> + {
>> + if ((status = poll(&fdset, 1, -1)) < 0)
>> + {
>> + switch (errno)
>> + {
>> + default:
>> + assert(false && "Unexpected poll() failure!");
>> + continue;
>> +
>> + case EINTR: continue; // Just poll again.
>> + case EBADF: return; // Connection terminated.
>> + }
>> + }
>> +
>> + assert(status == 1 && "Too many descriptors!");
>> +
>> + if (fdset.revents & POLLIN)
>> + {
>> + Operation *op = NULL;
>> +
>> + READ_AGAIN:
>> + if ((status = read(fdset.fd, &op, sizeof(op))) < 0)
>> + {
>> + // There is only one acceptable failure.
>> + assert(errno == EINTR);
>> + goto READ_AGAIN;
>> + }
>> +
>> + assert(status == sizeof(op));
>> + op->Execute(monitor);
>> + write(fdset.fd, &op, sizeof(op));
>> + }
>> + }
>> +}
>> +
>> +void
>> +ProcessMonitor::DoOperation(Operation *op)
>> +{
>> + int status;
>> + Operation *ack = NULL;
>> + Mutex::Locker lock(m_server_mutex);
>> +
>> + // FIXME: Do proper error checking here.
>> + write(m_client_fd, &op, sizeof(op));
>> +
>> +READ_AGAIN:
>> + if ((status = read(m_client_fd, &ack, sizeof(ack))) < 0)
>> + {
>> + // If interrupted by a signal handler try again. Otherwise the monitor
>> + // thread probably died and we have a stale file descriptor -- abort the
>> + // operation.
>> + if (errno == EINTR)
>> + goto READ_AGAIN;
>> + return;
>> + }
>> +
>> + assert(status == sizeof(ack));
>> + assert(ack == op && "Invalid monitor thread response!");
>> +}
>> +
>> +size_t
>> +ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
>> + Error &error)
>> +{
>> + size_t result;
>> + ReadOperation op(vm_addr, buf, size, error, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +size_t
>> +ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
>> + lldb_private::Error &error)
>> +{
>> + size_t result;
>> + WriteOperation op(vm_addr, buf, size, error, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::ReadRegisterValue(unsigned offset, unsigned size, RegisterValue &value)
>> +{
>> + bool result;
>> + ReadRegOperation op(offset, size, value, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::WriteRegisterValue(unsigned offset, const RegisterValue &value)
>> +{
>> + bool result;
>> + WriteRegOperation op(offset, value, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::ReadGPR(void *buf)
>> +{
>> + bool result;
>> + ReadGPROperation op(buf, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::ReadFPR(void *buf)
>> +{
>> + bool result;
>> + ReadFPROperation op(buf, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::WriteGPR(void *buf)
>> +{
>> + bool result;
>> + WriteGPROperation op(buf, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::WriteFPR(void *buf)
>> +{
>> + bool result;
>> + WriteFPROperation op(buf, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo)
>> +{
>> + bool result;
>> + ResumeOperation op(tid, signo, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::SingleStep(lldb::tid_t tid, uint32_t signo)
>> +{
>> + bool result;
>> + SingleStepOperation op(tid, signo, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::BringProcessIntoLimbo()
>> +{
>> + bool result;
>> + KillOperation op(result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo)
>> +{
>> + bool result;
>> + SiginfoOperation op(tid, siginfo, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message)
>> +{
>> + bool result;
>> + EventMessageOperation op(tid, message, result);
>> + DoOperation(&op);
>> + return result;
>> +}
>> +
>> +Error
>> +ProcessMonitor::Detach()
>> +{
>> + Error result;
>> + DetachOperation op(result);
>> + DoOperation(&op);
>> + StopMonitor();
>> + return result;
>> +}
>> +
>> +bool
>> +ProcessMonitor::DupDescriptor(const char *path, int fd, int flags)
>> +{
>> + int target_fd = open(path, flags, 0666);
>> +
>> + if (target_fd == -1)
>> + return false;
>> +
>> + return (dup2(target_fd, fd) == -1) ? false : true;
>> +}
>> +
>> +void
>> +ProcessMonitor::StopMonitoringChildProcess()
>> +{
>> + lldb::thread_result_t thread_result;
>> +
>> + if (IS_VALID_LLDB_HOST_THREAD(m_monitor_thread))
>> + {
>> + Host::ThreadCancel(m_monitor_thread, NULL);
>> + Host::ThreadJoin(m_monitor_thread, &thread_result, NULL);
>> + m_monitor_thread = LLDB_INVALID_HOST_THREAD;
>> + }
>> +}
>> +
>> +void
>> +ProcessMonitor::StopMonitor()
>> +{
>> + StopMonitoringChildProcess();
>> + StopLaunchOpThread();
>> + CloseFD(m_terminal_fd);
>> + CloseFD(m_client_fd);
>> + CloseFD(m_server_fd);
>> +}
>> +
>> +void
>> +ProcessMonitor::CloseFD(int &fd)
>> +{
>> + if (fd != -1)
>> + {
>> + close(fd);
>> + fd = -1;
>> + }
>> +}
>> Index: source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h
>> ===================================================================
>> --- source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h (revision 0)
>> +++ source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h (revision 0)
>> @@ -0,0 +1,43 @@
>> +//===-- RegisterContextFreeBSD_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 liblldb_RegisterContextFreeBSD_x86_64_H_
>> +#define liblldb_RegisterContextFreeBSD_x86_64_H_
>> +
>> + typedef struct _GPR
>> + {
>> + uint64_t r15;
>> + uint64_t r14;
>> + uint64_t r13;
>> + uint64_t r12;
>> + uint64_t r11;
>> + uint64_t r10;
>> + uint64_t r9;
>> + uint64_t r8;
>> + uint64_t rdi;
>> + uint64_t rsi;
>> + uint64_t rbp;
>> + uint64_t rbx;
>> + uint64_t rdx;
>> + uint64_t rcx;
>> + uint64_t rax;
>> + uint32_t trapno;
>> + uint16_t fs;
>> + uint16_t gs;
>> + uint32_t err;
>> + uint16_t es;
>> + uint16_t ds;
>> + uint64_t rip;
>> + uint64_t cs;
>> + uint64_t rflags;
>> + uint64_t rsp;
>> + uint64_t ss;
>> + } GPR;
>> +
>> +#endif
>> Index: source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
>> ===================================================================
>> --- source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp (revision 0)
>> +++ source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp (revision 0)
>> @@ -0,0 +1,136 @@
>> +//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++ -*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +// C Includes
>> +#include <errno.h>
>> +
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +#include "lldb/Core/PluginManager.h"
>> +#include "lldb/Core/State.h"
>> +#include "lldb/Host/Host.h"
>> +#include "lldb/Symbol/ObjectFile.h"
>> +#include "lldb/Target/DynamicLoader.h"
>> +#include "lldb/Target/Target.h"
>> +
>> +#include "ProcessFreeBSD.h"
>> +#include "ProcessPOSIXLog.h"
>> +#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
>> +#include "ProcessMonitor.h"
>> +#include "POSIXThread.h"
>> +
>> +using namespace lldb;
>> +using namespace lldb_private;
>> +
>> +//------------------------------------------------------------------------------
>> +// Static functions.
>> +
>> +Process*
>> +ProcessFreeBSD::CreateInstance(Target& target, Listener &listener)
>> +{
>> + return new ProcessFreeBSD(target, listener);
>> +}
>> +
>> +void
>> +ProcessFreeBSD::Initialize()
>> +{
>> + static bool g_initialized = false;
>> +
>> + if (!g_initialized)
>> + {
>> + PluginManager::RegisterPlugin(GetPluginNameStatic(),
>> + GetPluginDescriptionStatic(),
>> + CreateInstance);
>> + Log::Callbacks log_callbacks = {
>> + ProcessPOSIXLog::DisableLog,
>> + ProcessPOSIXLog::EnableLog,
>> + ProcessPOSIXLog::ListLogCategories
>> + };
>> +
>> + Log::RegisterLogChannel (ProcessFreeBSD::GetPluginNameStatic(), log_callbacks);
>> + ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic());
>> + g_initialized = true;
>> + }
>> +}
>> +
>> +const char *
>> +ProcessFreeBSD::GetPluginNameStatic()
>> +{
>> + return "freebsd";
>> +}
>> +
>> +const char *
>> +ProcessFreeBSD::GetPluginDescriptionStatic()
>> +{
>> + return "Process plugin for FreeBSD";
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +// ProcessInterface protocol.
>> +
>> +const char *
>> +ProcessFreeBSD::GetPluginName()
>> +{
>> + return "process.freebsd";
>> +}
>> +
>> +const char *
>> +ProcessFreeBSD::GetShortPluginName()
>> +{
>> + return "process.freebsd";
>> +}
>> +
>> +uint32_t
>> +ProcessFreeBSD::GetPluginVersion()
>> +{
>> + return 1;
>> +}
>> +
>> +void
>> +ProcessFreeBSD::GetPluginCommandHelp(const char *command, Stream *strm)
>> +{
>> +}
>> +
>> +Error
>> +ProcessFreeBSD::ExecutePluginCommand(Args &command, Stream *strm)
>> +{
>> + return Error(1, eErrorTypeGeneric);
>> +}
>> +
>> +Log *
>> +ProcessFreeBSD::EnablePluginLogging(Stream *strm, Args &command)
>> +{
>> + return NULL;
>> +}
>> +
>> +//------------------------------------------------------------------------------
>> +// Constructors and destructors.
>> +
>> +ProcessFreeBSD::ProcessFreeBSD(Target& target, Listener &listener)
>> + : ProcessPOSIX(target, listener)
>> +{
>> + // FIXME: Putting this code in the ctor and saving the byte order in a
>> + // member variable is a hack to avoid const qual issues in GetByteOrder.
>> + ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
>> + m_byte_order = obj_file->GetByteOrder();
>> +}
>> +
>> +void
>> +ProcessFreeBSD::Terminate()
>> +{
>> +}
>> +
>> +uint32_t
>> +ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
>> +{
>> + // XXX haxx
>> + new_thread_list = old_thread_list;
>> +
>> + return 0;
>> +}
>> Index: source/Plugins/Process/FreeBSD/ProcessMonitor.h
>> ===================================================================
>> --- source/Plugins/Process/FreeBSD/ProcessMonitor.h (revision 0)
>> +++ source/Plugins/Process/FreeBSD/ProcessMonitor.h (revision 0)
>> @@ -0,0 +1,292 @@
>> +//===-- ProcessMonitor.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_ProcessMonitor_H_
>> +#define liblldb_ProcessMonitor_H_
>> +
>> +// C Includes
>> +#include <semaphore.h>
>> +#include <signal.h>
>> +
>> +// C++ Includes
>> +// Other libraries and framework includes
>> +#include "lldb/lldb-types.h"
>> +#include "lldb/Host/Mutex.h"
>> +
>> +namespace lldb_private
>> +{
>> +class Error;
>> +class Module;
>> +class Scalar;
>> +} // End lldb_private namespace.
>> +
>> +class ProcessFreeBSD;
>> +class Operation;
>> +
>> +/// @class ProcessMonitor
>> +/// @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 propagated to the associated
>> +/// ProcessFreeBSD instance by calling ProcessFreeBSD::SendMessage with the
>> +/// appropriate ProcessMessage events.
>> +///
>> +/// A purposely minimal set of operations are provided to interrogate and change
>> +/// the inferior process state.
>> +class ProcessMonitor
>> +{
>> +public:
>> +
>> + /// Launches an inferior process ready for debugging. Forms the
>> + /// implementation of Process::DoLaunch.
>> + ProcessMonitor(ProcessPOSIX *process,
>> + lldb_private::Module *module,
>> + char const *argv[],
>> + char const *envp[],
>> + const char *stdin_path,
>> + const char *stdout_path,
>> + const char *stderr_path,
>> + lldb_private::Error &error);
>> +
>> + ProcessMonitor(ProcessPOSIX *process,
>> + lldb::pid_t pid,
>> + lldb_private::Error &error);
>> +
>> + ~ProcessMonitor();
>> +
>> + /// Provides the process number of debugee.
>> + lldb::pid_t
>> + GetPID() const { return m_pid; }
>> +
>> + /// Returns the process associated with this ProcessMonitor.
>> + ProcessFreeBSD &
>> + GetProcess() { return *m_process; }
>> +
>> + /// Returns a file descriptor to the controlling terminal of the inferior
>> + /// process.
>> + ///
>> + /// Reads from this file descriptor yield both the standard output and
>> + /// standard error of this debugee. Even if stderr and stdout were
>> + /// redirected on launch it may still happen that data is available on this
>> + /// descriptor (if the inferior process opens /dev/tty, for example).
>> + ///
>> + /// If this monitor was attached to an existing process this method returns
>> + /// -1.
>> + int
>> + GetTerminalFD() const { return m_terminal_fd; }
>> +
>> + /// Reads @p size bytes from address @vm_adder in the inferior process
>> + /// address space.
>> + ///
>> + /// This method is provided to implement Process::DoReadMemory.
>> + size_t
>> + ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
>> + lldb_private::Error &error);
>> +
>> + /// Writes @p size bytes from address @p vm_adder in the inferior process
>> + /// address space.
>> + ///
>> + /// This method is provided to implement Process::DoWriteMemory.
>> + size_t
>> + WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
>> + lldb_private::Error &error);
>> +
>> + /// Reads the contents from the register identified by the given (architecture
>> + /// dependent) offset.
>> + ///
>> + /// This method is provided for use by RegisterContextFreeBSD derivatives.
>> + bool
>> + ReadRegisterValue(unsigned offset, 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 RegisterContextFreeBSD derivatives.
>> + bool
>> + WriteRegisterValue(unsigned offset, const lldb_private::RegisterValue &value);
>> +
>> + /// Reads all general purpose registers into the specified buffer.
>> + bool
>> + ReadGPR(void *buf);
>> +
>> + /// Reads all floating point registers into the specified buffer.
>> + bool
>> + ReadFPR(void *buf);
>> +
>> + /// Writes all general purpose registers into the specified buffer.
>> + bool
>> + WriteGPR(void *buf);
>> +
>> + /// Writes all floating point registers into the specified buffer.
>> + bool
>> + WriteFPR(void *buf);
>> +
>> + /// 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);
>> +
>> + /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
>> + /// corresponding to the given thread IDto 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);
>> +
>> + /// Sends the inferior process a PTRACE_KILL signal. The inferior will
>> + /// still exists and can be interrogated. Once resumed it will exit as
>> + /// though it received a SIGKILL.
>> + bool
>> + BringProcessIntoLimbo();
>> +
>> + lldb_private::Error
>> + Detach();
>> +
>> +
>> +private:
>> + ProcessFreeBSD *m_process;
>> +
>> + lldb::thread_t m_operation_thread;
>> + lldb::thread_t m_monitor_thread;
>> + lldb::pid_t m_pid;
>> +
>> +
>> + lldb_private::Mutex m_server_mutex;
>> + int m_terminal_fd;
>> + int m_client_fd;
>> + int m_server_fd;
>> +
>> + struct OperationArgs
>> + {
>> + OperationArgs(ProcessMonitor *monitor);
>> +
>> + ~OperationArgs();
>> +
>> + ProcessMonitor *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(ProcessMonitor *monitor,
>> + lldb_private::Module *module,
>> + char const **argv,
>> + char const **envp,
>> + const char *stdin_path,
>> + const char *stdout_path,
>> + const char *stderr_path);
>> +
>> + ~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.
>> + };
>> +
>> + void
>> + StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);
>> +
>> + void
>> + StopLaunchOpThread();
>> +
>> + static void *
>> + LaunchOpThread(void *arg);
>> +
>> + static bool
>> + Launch(LaunchArgs *args);
>> +
>> + bool
>> + EnableIPC();
>> +
>> + struct AttachArgs : OperationArgs
>> + {
>> + AttachArgs(ProcessMonitor *monitor,
>> + lldb::pid_t pid);
>> +
>> + ~AttachArgs();
>> +
>> + lldb::pid_t m_pid; // pid of the process to be attached.
>> + };
>> +
>> + void
>> + StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);
>> +
>> + void
>> + StopAttachOpThread();
>> +
>> + static void *
>> + AttachOpThread(void *args);
>> +
>> + static bool
>> + Attach(AttachArgs *args);
>> +
>> + 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);
>> +
>> + static ProcessMessage
>> + MonitorSIGTRAP(ProcessMonitor *monitor,
>> + const siginfo_t *info, lldb::pid_t pid);
>> +
>> + static ProcessMessage
>> + MonitorSignal(ProcessMonitor *monitor,
>> + const siginfo_t *info, lldb::pid_t pid);
>> +
>> + 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);
>> +
>> + void
>> + DoOperation(Operation *op);
>> +
>> + /// Stops the child monitor thread.
>> + void
>> + StopMonitoringChildProcess();
>> +
>> + void
>> + StopMonitor();
>> +
>> + void
>> + CloseFD(int &fd);
>> +};
>> +
>> +#endif // #ifndef liblldb_ProcessMonitor_H_
>> Index: source/Plugins/Process/FreeBSD/Makefile
>> ===================================================================
>> --- source/Plugins/Process/FreeBSD/Makefile (revision 0)
>> +++ source/Plugins/Process/FreeBSD/Makefile (revision 0)
>> @@ -0,0 +1,17 @@
>> +##===- source/Plugins/Process/FreeBSD/Makefile ---------------*- Makefile -*-===##
>> +#
>> +# The LLVM Compiler Infrastructure
>> +#
>> +# This file is distributed under the University of Illinois Open Source
>> +# License. See LICENSE.TXT for details.
>> +#
>> +##===----------------------------------------------------------------------===##
>> +
>> +LLDB_LEVEL := ../../../..
>> +LIBRARYNAME := lldbPluginProcessFreeBSD
>> +BUILD_ARCHIVE = 1
>> +
>> +# Extend the include path so we may locate UnwindLLDB.h
>> +CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility
>> +
>> +include $(LLDB_LEVEL)/Makefile
>> Index: source/Host/linux/Host.cpp
>> ===================================================================
>> --- source/Host/linux/Host.cpp (revision 147560)
>> +++ source/Host/linux/Host.cpp (working copy)
>> @@ -10,12 +10,20 @@
>> // C Includes
>> #include <stdio.h>
>> #include <sys/utsname.h>
>> +#include <sys/types.h>
>> +#include <sys/stat.h>
>> +#include <fcntl.h>
>>
>> +
>> // 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<DataBufferHeap> 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 147560)
>> +++ source/Host/freebsd/Host.cpp (working copy)
>> @@ -9,12 +9,18 @@
>>
>> // C Includes
>> #include <stdio.h>
>> +#include <dlfcn.h>
>> #include <execinfo.h>
>> #include <sys/types.h>
>> #include <sys/user.h>
>> #include <sys/utsname.h>
>> #include <sys/sysctl.h>
>>
>> +#include <sys/ptrace.h>
>> +#include <sys/exec.h>
>> +#include <machine/elf.h>
>> +
>> +
>> // 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:
>> @@ -77,7 +87,7 @@
>> std::vector<void *> frame_buffer (max_frames, NULL);
>> int count = ::backtrace (&frame_buffer[0], frame_buffer.size());
>> ::backtrace_symbols_fd (&frame_buffer[0], count, backtrace_fd);
>> -
>> +
>> const off_t buffer_size = ::lseek(backtrace_fd, 0, SEEK_CUR);
>>
>> if (::lseek(backtrace_fd, 0, SEEK_SET) == 0)
>> @@ -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,49 +178,47 @@
>> 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);
>> if (cstr)
>> {
>> 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()))
>> + match_info_ptr->GetProcessInfo().GetName())))
>> + return false;
>> +
>> + Args &proc_args = process_info.GetArguments();
>> + while (1)
>> {
>> - // Skip NULLs
>> - while (1)
>> + const uint8_t *p = data.PeekData(offset, 1);
>> + while ((p != NULL) && (*p == '\0') && offset < arg_data_size)
>> {
>> - const uint8_t *p = data.PeekData(offset, 1);
>> - if ((p == NULL) || (*p != '\0'))
>> - break;
>> ++offset;
>> + p = data.PeekData(offset, 1);
>> }
>> - // Now extract all arguments
>> - Args &proc_args = process_info.GetArguments();
>> - for (int i=0; i<argc; ++i)
>> - {
>> - start_offset = offset;
>> - cstr = data.GetCStr(&offset);
>> - if (cstr)
>> - proc_args.AppendArgument(cstr);
>> - }
>> - return true;
>> + 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 +227,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;
>> @@ -249,7 +257,7 @@
>> if (proc_kinfo.ki_ngroups > 0)
>> process_info.SetEffectiveGroupID (proc_kinfo.ki_groups[0]);
>> else
>> - process_info.SetEffectiveGroupID (UINT32_MAX);
>> + process_info.SetEffectiveGroupID (UINT32_MAX);
>> return true;
>> }
>> }
>> @@ -258,7 +266,7 @@
>> process_info.SetUserID (UINT32_MAX);
>> process_info.SetGroupID (UINT32_MAX);
>> process_info.SetEffectiveUserID (UINT32_MAX);
>> - process_info.SetEffectiveGroupID (UINT32_MAX);
>> + process_info.SetEffectiveGroupID (UINT32_MAX);
>> return false;
>> }
>>
>> @@ -275,3 +283,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<DataBufferHeap> 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;
>> +}
>> Index: source/lldb.cpp
>> ===================================================================
>> --- source/lldb.cpp (revision 147560)
>> +++ 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: tools/driver/Makefile
>> ===================================================================
>> --- tools/driver/Makefile (revision 147560)
>> +++ 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 147560)
>> +++ 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
>> @@ -130,8 +134,8 @@
>> # Include everything from the .a's into the shared library.
>> ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
>> -Wl,--no-whole-archive
>> - # Don't allow unresolved symbols.
>> - LLVMLibsOptions += -Wl,--no-undefined
>> + # Allow unresolved symbols.
>> + LLVMLibsOptions += -Wl,--allow-shlib-undefined
>> # Link in python
>> LD.Flags += $(PYTHON_BUILD_FLAGS) -lrt -L/usr/local/lib -lexecinfo
>> endif
>> Index: Makefile
>> ===================================================================
>> --- Makefile (revision 147560)
>> +++ 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
>
>> _______________________________________________
>> lldb-commits mailing list
>> lldb-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
>
More information about the lldb-commits
mailing list