diff options
Diffstat (limited to 'lldb/source')
32 files changed, 248 insertions, 5242 deletions
diff --git a/lldb/source/Host/freebsd/Host.cpp b/lldb/source/Host/freebsd/Host.cpp index 3d6596c028f..3a4174f7548 100644 --- a/lldb/source/Host/freebsd/Host.cpp +++ b/lldb/source/Host/freebsd/Host.cpp @@ -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 @@ Host::Backtrace (Stream &strm, uint32_t max_frames) 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 @@ Host::GetEnvironment (StringList &env) { 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 @@ GetFreeBSDProcessArgs (const ProcessInstanceInfoMatch *match_info_ptr, 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 @@ static bool 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 @@ GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) 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 @@ GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) 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 @@ Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 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; +} diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index 4ebacc54c17..432dfd509de 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -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 @@ Host::LaunchProcess (ProcessLaunchInfo &launch_info) 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; +} diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp index 6954e4cac4d..e69de29bb2d 100644 --- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp +++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp @@ -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; -} - diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h index 7a5b3700fce..e69de29bb2d 100644 --- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h +++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h @@ -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 diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp index f10aedb63de..e69de29bb2d 100644 --- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp +++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp @@ -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); - } -} diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h index e8052ae5b3e..e69de29bb2d 100644 --- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h +++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h @@ -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 diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp index caad7a01f9a..e69de29bb2d 100644 --- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp @@ -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; -} diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h index bead75c76dd..e69de29bb2d 100644 --- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h +++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h @@ -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_ diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile index 94025dd3eba..e69de29bb2d 100644 --- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile +++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile @@ -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 diff --git a/lldb/source/Plugins/Makefile b/lldb/source/Plugins/Makefile index c712361e116..0aae174a595 100644 --- a/lldb/source/Plugins/Makefile +++ b/lldb/source/Plugins/Makefile @@ -30,7 +30,11 @@ DIRS += OperatingSystem/Darwin-Kernel 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 diff --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp index ec9e4d92c73..a81010c7672 100644 --- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -27,16 +27,13 @@ using namespace lldb_private; 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 @@ PlatformFreeBSD::Initialize () { #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 @@ PlatformFreeBSD::Initialize () void PlatformFreeBSD::Terminate () { - PluginManager::UnregisterPlugin (PlatformFreeBSD::CreateInstance); + PluginManager::UnregisterPlugin (PlatformFreeBSD::CreateInstance); } //------------------------------------------------------------------ @@ -385,17 +382,16 @@ PlatformFreeBSD::DisconnectRemote () 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 @@ PlatformFreeBSD::LaunchProcess (ProcessLaunchInfo &launch_info) } 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 @@ PlatformFreeBSD::Attach(lldb::pid_t pid, emptyFileSpec, emptyArchSpec, false, + m_remote_platform_sp, new_target_sp); target = new_target_sp.get(); } @@ -472,13 +469,13 @@ PlatformFreeBSD::Attach(lldb::pid_t pid, 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"); } diff --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h index d245af6bcb6..99bbb0135d9 100644 --- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h +++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h @@ -132,12 +132,16 @@ public: 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, diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h index da907bb4aa9..5935002c58b 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h @@ -104,6 +104,7 @@ namespace lldb_private { 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 () { diff --git a/lldb/source/Plugins/Process/Linux/LinuxStopInfo.cpp b/lldb/source/Plugins/Process/Linux/LinuxStopInfo.cpp index 5bcafbd5072..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/LinuxStopInfo.cpp +++ b/lldb/source/Plugins/Process/Linux/LinuxStopInfo.cpp @@ -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); -} diff --git a/lldb/source/Plugins/Process/Linux/LinuxStopInfo.h b/lldb/source/Plugins/Process/Linux/LinuxStopInfo.h index 96b402a594c..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/LinuxStopInfo.h +++ b/lldb/source/Plugins/Process/Linux/LinuxStopInfo.h @@ -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 diff --git a/lldb/source/Plugins/Process/Linux/LinuxThread.cpp b/lldb/source/Plugins/Process/Linux/LinuxThread.cpp index 7745cc9360f..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/LinuxThread.cpp +++ b/lldb/source/Plugins/Process/Linux/LinuxThread.cpp @@ -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)); -} - diff --git a/lldb/source/Plugins/Process/Linux/LinuxThread.h b/lldb/source/Plugins/Process/Linux/LinuxThread.h index f6253107d24..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/LinuxThread.h +++ b/lldb/source/Plugins/Process/Linux/LinuxThread.h @@ -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_ diff --git a/lldb/source/Plugins/Process/Linux/Makefile b/lldb/source/Plugins/Process/Linux/Makefile index d2260f5cad3..850a0290b62 100644 --- a/lldb/source/Plugins/Process/Linux/Makefile +++ b/lldb/source/Plugins/Process/Linux/Makefile @@ -12,6 +12,6 @@ LIBRARYNAME := lldbPluginProcessLinux 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 diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp index 2171a6dbb2f..a8c33bc701d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp @@ -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 @@ ProcessLinux::Initialize() 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 @@ ProcessLinux::ProcessLinux(Target& target, Listener &listener) #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() -{ -} - -Error -ProcessLinux::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) - { - 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(); -} - -addr_t -ProcessLinux::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 -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) +ProcessLinux::Terminate() { - 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) +const char * +ProcessLinux::GetPluginNameStatic() { - return EnableSoftwareBreakpoint(bp_site); + return "linux"; } -Error -ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site) +const char * +ProcessLinux::GetPluginDescriptionStatic() { - return DisableSoftwareBreakpoint(bp_site); + return "Process plugin for Linux"; } -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,61 +106,15 @@ ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thre 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 @@ ProcessLinux::EnablePluginLogging(Stream *strm, Args &command) { 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; -} diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.h b/lldb/source/Plugins/Process/Linux/ProcessLinux.h index 1f67d54de63..cef8a662171 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/ProcessLinux.h @@ -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 @@ public: 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 @@ public: 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_ diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.cpp b/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.cpp index c07263e891c..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.cpp @@ -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; diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.h b/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.h index 0553df6d1e4..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.h +++ b/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.h @@ -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_ diff --git a/lldb/source/Plugins/Process/Linux/ProcessMessage.cpp b/lldb/source/Plugins/Process/Linux/ProcessMessage.cpp index ad3fc7f3629..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMessage.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMessage.cpp @@ -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); -} diff --git a/lldb/source/Plugins/Process/Linux/ProcessMessage.h b/lldb/source/Plugins/Process/Linux/ProcessMessage.h index 826567e582b..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMessage.h +++ b/lldb/source/Plugins/Process/Linux/ProcessMessage.h @@ -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_ diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp index c154c5555db..ed69b970f20 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -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 @@ DisplayBytes (lldb_private::StreamString &s, void *bytes, uint32_t count) 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 @@ PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, { 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 @@ DoReadMemory(lldb::pid_t pid, unsigned word_size, 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 @@ DoReadMemory(lldb::pid_t pid, unsigned word_size, { error.SetErrorToErrno(); if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_read; } @@ -200,10 +200,10 @@ DoReadMemory(lldb::pid_t pid, unsigned word_size, 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 @@ DoReadMemory(lldb::pid_t pid, unsigned word_size, } if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_read; } @@ -224,10 +224,10 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, 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 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, 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 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, { error.SetErrorToErrno(); if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } } @@ -266,7 +266,7 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, buff, word_size, error) != word_size) { if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } @@ -276,14 +276,14 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, 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 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, src += word_size; } if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } @@ -420,7 +420,7 @@ void 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 @@ ReadRegOperation::Execute(ProcessMonitor *monitor) } 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 @@ WriteRegOperation::Execute(ProcessMonitor *monitor) { 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 @@ WriteRegOperation::Execute(ProcessMonitor *monitor) 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 @@ ProcessMonitor::AttachArgs::~AttachArgs() /// 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 @@ ProcessMonitor::ProcessMonitor(ProcessLinux *process, 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 @@ WAIT_AGAIN: } } -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 @@ ProcessMonitor::Launch(LaunchArgs *args) 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 @@ ProcessMonitor::Launch(LaunchArgs *args) 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::Attach(AttachArgs *args) 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 @@ ProcessMonitor::Attach(AttachArgs *args) 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 @@ ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, } bool -ProcessMonitor::ReadRegisterValue(unsigned offset, RegisterValue &value) +ProcessMonitor::ReadRegisterValue(unsigned offset, unsigned size, RegisterValue &value) { bool result; ReadRegOperation op(offset, value, result); diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h index fdccb67745a..03e8c8c4558 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h @@ -24,10 +24,12 @@ namespace lldb_private 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 @@ public: /// 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 @@ public: 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 @@ public: /// /// 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. diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux.h b/lldb/source/Plugins/Process/Linux/RegisterContextLinux.h index 4e5d4651f8b..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux.h +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux.h @@ -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_ diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp index 20c3c73c589..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp @@ -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); -} diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.h b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.h index 718e831abb0..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.h +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.h @@ -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_ diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp index 040c14eda51..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp @@ -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); -} diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h index def85f6840d..3dc6c7298da 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h @@ -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 @@ public: uint64_t es; uint64_t fs; uint64_t gs; - }; - - 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(); -}; + } GPR; -#endif // #ifndef liblldb_RegisterContextLinux_x86_64_H_ +#endif diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp index cbea0a144bd..18c9c198d0f 100644 --- a/lldb/source/lldb.cpp +++ b/lldb/source/lldb.cpp @@ -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 @@ lldb_private::Initialize () //---------------------------------------------------------------------- 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 @@ lldb_private::Terminate () #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(); |