[Lldb-commits] [lldb] r186207 - Introduces core file support for Linux x86-64 using 'lldb a.out -c core'.
Greg Clayton
gclayton at apple.com
Fri Jul 12 15:30:35 PDT 2013
This breaks the MacOSX build. I added the files that were needed into the Xcode project, but here is the problem:
RegisterContextCoreLinux_x86_64 inherits from RegisterContextLinux_x86_64 which inherits from RegisterContext_x86_64 which uses has:
ProcessMonitor &GetMonitor();
This register context used by the core file can't use this since the process plug-in will be ProcessElfCore and the implementation of GetMonitor() does:
ProcessMonitor &
RegisterContext_x86_64::GetMonitor()
{
ProcessSP base = CalculateProcess();
ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
return process->GetMonitor();
}
ProcessELFCore doesn't, nor should it inherit from ProcessPOSIX:
class ProcessElfCore : public lldb_private::Process
{
public:
On Jul 12, 2013, at 2:25 PM, Ashok Thirumurthi <ashok.thirumurthi at intel.com> wrote:
> Author: athirumu
> Date: Fri Jul 12 16:25:02 2013
> New Revision: 186207
>
> URL: http://llvm.org/viewvc/llvm-project?rev=186207&view=rev
> Log:
> Introduces core file support for Linux x86-64 using 'lldb a.out -c core'.
> TODO: Support for RegisterContext_x86_64::ReadFPR.
>
> Patch by Samuel Jacob!
>
> Added:
> lldb/trunk/source/Plugins/Process/elf-core/
> lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt
> lldb/trunk/source/Plugins/Process/elf-core/Makefile
> lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
> lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h
> lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.cpp
> lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.h
> lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.cpp
> lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.h
> lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp
> lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h
> Modified:
> lldb/trunk/lib/Makefile
> lldb/trunk/source/CMakeLists.txt
> lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
> lldb/trunk/source/Plugins/Makefile
> lldb/trunk/source/Plugins/Process/CMakeLists.txt
> lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp
> lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h
> lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
> lldb/trunk/source/lldb.cpp
>
> Modified: lldb/trunk/lib/Makefile
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lib/Makefile?rev=186207&r1=186206&r2=186207&view=diff
> ==============================================================================
> --- lldb/trunk/lib/Makefile (original)
> +++ lldb/trunk/lib/Makefile Fri Jul 12 16:25:02 2013
> @@ -67,6 +67,7 @@ USEDLIBS = lldbAPI.a \
> LLVMMCDisassembler.a \
> lldbPluginPlatformMacOSX.a \
> lldbPluginPlatformLinux.a \
> + lldbPluginProcessElfCore.a \
> lldbPluginPlatformFreeBSD.a
>
> # Because GCC requires RTTI enabled for lldbCore (see source/Core/Makefile) it is
>
> Modified: lldb/trunk/source/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/CMakeLists.txt?rev=186207&r1=186206&r2=186207&view=diff
> ==============================================================================
> --- lldb/trunk/source/CMakeLists.txt (original)
> +++ lldb/trunk/source/CMakeLists.txt Fri Jul 12 16:25:02 2013
> @@ -90,6 +90,7 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Linux" )
> lldbHostLinux
> lldbPluginProcessLinux
> lldbPluginProcessPOSIX
> + lldbPluginProcessElfCore
> )
> endif ()
>
>
> Modified: lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp?rev=186207&r1=186206&r2=186207&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp (original)
> +++ lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp Fri Jul 12 16:25:02 2013
> @@ -19,6 +19,8 @@
> #include "lldb/Core/Log.h"
> #include "lldb/Target/Process.h"
>
> +#include "Plugins/Process/elf-core/ProcessElfCore.h"
> +
> #include "AuxVector.h"
>
> using namespace lldb;
> @@ -53,8 +55,10 @@ ParseAuxvEntry(DataExtractor &data,
> DataBufferSP
> AuxVector::GetAuxvData()
> {
> -
> - return lldb_private::Host::GetAuxvData(m_process);
> + if (m_process->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
> + return static_cast<ProcessElfCore *>(m_process)->GetAuxvData();
> + else
> + return lldb_private::Host::GetAuxvData(m_process);
> }
>
> void
>
> Modified: lldb/trunk/source/Plugins/Makefile
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Makefile?rev=186207&r1=186206&r2=186207&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Makefile (original)
> +++ lldb/trunk/source/Plugins/Makefile Fri Jul 12 16:25:02 2013
> @@ -35,6 +35,7 @@ ifeq ($(HOST_OS),Linux)
> DIRS += DynamicLoader/MacOSX-DYLD
> DIRS += Process/Linux Process/POSIX
> DIRS += SymbolVendor/ELF
> +DIRS += Process/elf-core
> endif
>
> ifneq (,$(filter $(HOST_OS), FreeBSD GNU/kFreeBSD))
>
> Modified: lldb/trunk/source/Plugins/Process/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/CMakeLists.txt?rev=186207&r1=186206&r2=186207&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/CMakeLists.txt (original)
> +++ lldb/trunk/source/Plugins/Process/CMakeLists.txt Fri Jul 12 16:25:02 2013
> @@ -1,6 +1,7 @@
> if (CMAKE_SYSTEM_NAME MATCHES "Linux")
> add_subdirectory(Linux)
> add_subdirectory(POSIX)
> + add_subdirectory(elf-core)
> elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
> add_subdirectory(FreeBSD)
> add_subdirectory(POSIX)
>
> Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp?rev=186207&r1=186206&r2=186207&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp (original)
> +++ lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp Fri Jul 12 16:25:02 2013
> @@ -32,9 +32,9 @@ using namespace lldb_private;
> // Static functions.
>
> ProcessSP
> -ProcessLinux::CreateInstance(Target &target, Listener &listener, const FileSpec *)
> +ProcessLinux::CreateInstance(Target &target, Listener &listener, const FileSpec *core_file)
> {
> - return ProcessSP(new ProcessLinux(target, listener));
> + return ProcessSP(new ProcessLinux(target, listener, (FileSpec *)core_file));
> }
>
> void
> @@ -63,9 +63,10 @@ ProcessLinux::Initialize()
> //------------------------------------------------------------------------------
> // Constructors and destructors.
>
> -ProcessLinux::ProcessLinux(Target& target, Listener &listener)
> +ProcessLinux::ProcessLinux(Target& target, Listener &listener, FileSpec *core_file)
> : ProcessPOSIX(target, listener), m_stopping_threads(false)
> {
> + m_core_file = core_file;
> #if 0
> // FIXME: Putting this code in the ctor and saving the byte order in a
> // member variable is a hack to avoid const qual issues in GetByteOrder.
> @@ -170,3 +171,17 @@ ProcessLinux::StopAllThreads(lldb::tid_t
> if (log)
> log->Printf ("ProcessLinux::%s() finished", __FUNCTION__);
> }
> +
> +bool
> +ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name)
> +{
> + if (plugin_specified_by_name)
> + return true;
> +
> + /* If core file is specified then let elf-core plugin handle it */
> + if (m_core_file)
> + return false;
> +
> + return ProcessPOSIX::CanDebug(target, plugin_specified_by_name);
> +}
> +
>
> Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h?rev=186207&r1=186206&r2=186207&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h (original)
> +++ lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h Fri Jul 12 16:25:02 2013
> @@ -51,7 +51,8 @@ public:
> // Constructors and destructors
> //------------------------------------------------------------------
> ProcessLinux(lldb_private::Target& target,
> - lldb_private::Listener &listener);
> + lldb_private::Listener &listener,
> + lldb_private::FileSpec *core_file);
>
> virtual bool
> UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list);
> @@ -84,6 +85,9 @@ public:
> return m_linux_signals;
> }
>
> + virtual bool
> + CanDebug(lldb_private::Target &target, bool plugin_specified_by_name);
> +
> //------------------------------------------------------------------
> // ProcessPOSIX overrides
> //------------------------------------------------------------------
> @@ -95,6 +99,8 @@ private:
> /// Linux-specific signal set.
> LinuxSignals m_linux_signals;
>
> + lldb_private::FileSpec *m_core_file;
> +
> // Flag to avoid recursion when stopping all threads.
> bool m_stopping_threads;
> };
>
> Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp?rev=186207&r1=186206&r2=186207&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp (original)
> +++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp Fri Jul 12 16:25:02 2013
> @@ -25,6 +25,7 @@
> #include "RegisterContext_i386.h"
> #include "RegisterContext_x86.h"
> #include "RegisterContext_x86_64.h"
> +#include "Plugins/Process/elf-core/ProcessElfCore.h"
>
> using namespace lldb_private;
> using namespace lldb;
> @@ -497,6 +498,11 @@ RegisterContext_x86_64::RegisterContext_
>
> ::memset(&m_fpr, 0, sizeof(RegisterContext_x86_64::FPR));
>
> + // elf-core yet to support ReadFPR()
> + ProcessSP base = CalculateProcess();
> + if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
> + return;
> +
> // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
> m_fpr_type = eXSAVE; // extended floating-point registers, if available
> if (false == ReadFPR())
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,10 @@
> +include_directories(../Utility)
> +
> +set(LLVM_NO_RTTI 1)
> +
> +add_lldb_library(lldbPluginProcessElfCore
> + ProcessElfCore.cpp
> + ThreadElfCore.cpp
> + RegisterContextCoreLinux_x86_64.cpp
> + RegisterContextCoreFreeBSD_x86_64.cpp
> + )
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/Makefile
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/Makefile?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/Makefile (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/Makefile Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,14 @@
> +##===- source/Plugins/Process/elf-core/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 := lldbPluginProcessElfCore
> +BUILD_ARCHIVE = 1
> +
> +include $(LLDB_LEVEL)/Makefile
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,518 @@
> +//===-- ProcessElfCore.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 <stdlib.h>
> +
> +// Other libraries and framework includes
> +#include "lldb/Core/PluginManager.h"
> +#include "lldb/Core/Module.h"
> +#include "lldb/Core/ModuleSpec.h"
> +#include "lldb/Core/Section.h"
> +#include "lldb/Core/State.h"
> +#include "lldb/Core/DataBufferHeap.h"
> +#include "lldb/Target/Target.h"
> +#include "lldb/Target/DynamicLoader.h"
> +
> +#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
> +#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
> +
> +// Project includes
> +#include "ProcessElfCore.h"
> +#include "ThreadElfCore.h"
> +
> +using namespace lldb_private;
> +
> +ConstString
> +ProcessElfCore::GetPluginNameStatic()
> +{
> + static ConstString g_name("elf-core");
> + return g_name;
> +}
> +
> +const char *
> +ProcessElfCore::GetPluginDescriptionStatic()
> +{
> + return "ELF core dump plug-in.";
> +}
> +
> +void
> +ProcessElfCore::Terminate()
> +{
> + PluginManager::UnregisterPlugin (ProcessElfCore::CreateInstance);
> +}
> +
> +
> +lldb::ProcessSP
> +ProcessElfCore::CreateInstance (Target &target, Listener &listener, const FileSpec *crash_file)
> +{
> + lldb::ProcessSP process_sp;
> + if (crash_file)
> + process_sp.reset(new ProcessElfCore (target, listener, *crash_file));
> + return process_sp;
> +}
> +
> +bool
> +ProcessElfCore::CanDebug(Target &target, bool plugin_specified_by_name)
> +{
> + // For now we are just making sure the file exists for a given module
> + if (!m_core_module_sp && m_core_file.Exists())
> + {
> + ModuleSpec core_module_spec(m_core_file, target.GetArchitecture());
> + Error error (ModuleList::GetSharedModule (core_module_spec, m_core_module_sp,
> + NULL, NULL, NULL));
> + if (m_core_module_sp)
> + {
> + ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
> + if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
> + return true;
> + }
> + }
> + return false;
> +}
> +
> +//----------------------------------------------------------------------
> +// ProcessElfCore constructor
> +//----------------------------------------------------------------------
> +ProcessElfCore::ProcessElfCore(Target& target, Listener &listener,
> + const FileSpec &core_file) :
> + Process (target, listener),
> + m_core_module_sp (),
> + m_core_file (core_file),
> + m_dyld_plugin_name (),
> + m_thread_data_valid(false),
> + m_thread_data(),
> + m_core_aranges ()
> +{
> +}
> +
> +//----------------------------------------------------------------------
> +// Destructor
> +//----------------------------------------------------------------------
> +ProcessElfCore::~ProcessElfCore()
> +{
> + Clear();
> + // We need to call finalize on the process before destroying ourselves
> + // to make sure all of the broadcaster cleanup goes as planned. If we
> + // destruct this class, then Process::~Process() might have problems
> + // trying to fully destroy the broadcaster.
> + Finalize();
> +}
> +
> +//----------------------------------------------------------------------
> +// PluginInterface
> +//----------------------------------------------------------------------
> +ConstString
> +ProcessElfCore::GetPluginName()
> +{
> + return GetPluginNameStatic();
> +}
> +
> +uint32_t
> +ProcessElfCore::GetPluginVersion()
> +{
> + return 1;
> +}
> +
> +lldb::addr_t
> +ProcessElfCore::AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header)
> +{
> + lldb::addr_t addr = header->p_vaddr;
> + FileRange file_range (header->p_offset, header->p_filesz);
> + VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range);
> +
> + VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
> + if (last_entry &&
> + last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
> + last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase())
> + {
> + last_entry->SetRangeEnd (range_entry.GetRangeEnd());
> + last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
> + }
> + else
> + {
> + m_core_aranges.Append(range_entry);
> + }
> +
> + return addr;
> +}
> +
> +//----------------------------------------------------------------------
> +// Process Control
> +//----------------------------------------------------------------------
> +Error
> +ProcessElfCore::DoLoadCore ()
> +{
> + Error error;
> + if (!m_core_module_sp)
> + {
> + error.SetErrorString ("invalid core module");
> + return error;
> + }
> +
> + ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
> + if (core == NULL)
> + {
> + error.SetErrorString ("invalid core object file");
> + return error;
> + }
> +
> + const uint32_t num_segments = core->GetProgramHeaderCount();
> + if (num_segments == 0)
> + {
> + error.SetErrorString ("core file has no sections");
> + return error;
> + }
> +
> + SetCanJIT(false);
> +
> + m_thread_data_valid = true;
> +
> + bool ranges_are_sorted = true;
> + lldb::addr_t vm_addr = 0;
> + /// Walk through segments and Thread and Address Map information.
> + /// PT_NOTE - Contains Thread and Register information
> + /// PT_LOAD - Contains a contiguous range of Process Address Space
> + for(uint32_t i = 1; i <= num_segments; i++)
> + {
> + const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i);
> + assert(header != NULL);
> +
> + DataExtractor data = core->GetSegmentDataByIndex(i);
> +
> + // Parse thread contexts and auxv structure
> + if (header->p_type == llvm::ELF::PT_NOTE)
> + ParseThreadContextsFromNoteSegment(header, data);
> +
> + // PT_LOAD segments contains address map
> + if (header->p_type == llvm::ELF::PT_LOAD)
> + {
> + lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header);
> + if (vm_addr > last_addr)
> + ranges_are_sorted = false;
> + vm_addr = last_addr;
> + }
> + }
> +
> + if (!ranges_are_sorted)
> + m_core_aranges.Sort();
> +
> + // Even if the architecture is set in the target, we need to override
> + // it to match the core file which is always single arch.
> + ArchSpec arch (m_core_module_sp->GetArchitecture());
> + switch (arch.GetCore())
> + {
> + case ArchSpec::eCore_x86_32_i486:
> + arch.SetTriple ("i386", m_target.GetPlatform().get());
> + break;
> + case ArchSpec::eCore_x86_64_x86_64:
> + arch.SetTriple ("x86_64-linux-gnu", m_target.GetPlatform().get());
> + break;
> + default:
> + assert(false && "Unhandled core type");
> + }
> + if (arch.IsValid())
> + m_target.SetArchitecture(arch);
> +
> + return error;
> +}
> +
> +lldb_private::DynamicLoader *
> +ProcessElfCore::GetDynamicLoader ()
> +{
> + if (m_dyld_ap.get() == NULL)
> + m_dyld_ap.reset (DynamicLoader::FindPlugin(this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
> + return m_dyld_ap.get();
> +}
> +
> +bool
> +ProcessElfCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
> +{
> + const uint32_t num_threads = GetNumThreadContexts ();
> + if (!m_thread_data_valid)
> + return false;
> +
> + for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
> + {
> + const ThreadData &td = m_thread_data[tid];
> + lldb::ThreadSP thread_sp(new ThreadElfCore (*this, tid, td.prstatus,
> + td.prpsinfo, td.fpregset));
> + new_thread_list.AddThread (thread_sp);
> + }
> + return new_thread_list.GetSize(false) > 0;
> +}
> +
> +void
> +ProcessElfCore::RefreshStateAfterStop ()
> +{
> +}
> +
> +Error
> +ProcessElfCore::DoDestroy ()
> +{
> + return Error();
> +}
> +
> +//------------------------------------------------------------------
> +// Process Queries
> +//------------------------------------------------------------------
> +
> +bool
> +ProcessElfCore::IsAlive ()
> +{
> + return true;
> +}
> +
> +//------------------------------------------------------------------
> +// Process Memory
> +//------------------------------------------------------------------
> +size_t
> +ProcessElfCore::ReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
> +{
> + // Don't allow the caching that lldb_private::Process::ReadMemory does
> + // since in core files we have it all cached our our core file anyway.
> + return DoReadMemory (addr, buf, size, error);
> +}
> +
> +size_t
> +ProcessElfCore::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
> +{
> + ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
> +
> + if (core_objfile == NULL)
> + return 0;
> +
> + // Get the address range
> + const VMRangeToFileOffset::Entry *address_range = m_core_aranges.FindEntryThatContains (addr);
> + if (address_range == NULL || address_range->GetRangeEnd() < addr)
> + {
> + error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
> + return 0;
> + }
> +
> + // Convert the address into core file offset
> + const lldb::addr_t offset = addr - address_range->GetRangeBase();
> + const lldb::addr_t file_start = address_range->data.GetRangeBase();
> + const lldb::addr_t file_end = address_range->data.GetRangeEnd();
> + size_t bytes_to_read = size; // Number of bytes to read from the core file
> + size_t bytes_copied = 0; // Number of bytes actually read from the core file
> + size_t zero_fill_size = 0; // Padding
> + lldb::addr_t bytes_left = 0; // Number of bytes available in the core file from the given address
> +
> + if (file_end > offset)
> + bytes_left = file_end - offset;
> +
> + if (bytes_to_read > bytes_left)
> + {
> + zero_fill_size = bytes_to_read - bytes_left;
> + bytes_to_read = bytes_left;
> + }
> +
> + // If there is data available on the core file read it
> + if (bytes_to_read)
> + bytes_copied = core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
> +
> + assert(zero_fill_size <= size);
> + // Pad remaining bytes
> + if (zero_fill_size)
> + memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
> +
> + return bytes_copied + zero_fill_size;
> +}
> +
> +void
> +ProcessElfCore::Clear()
> +{
> + m_thread_list.Clear();
> +}
> +
> +void
> +ProcessElfCore::Initialize()
> +{
> + static bool g_initialized = false;
> +
> + if (g_initialized == false)
> + {
> + g_initialized = true;
> + PluginManager::RegisterPlugin (GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance);
> + }
> +}
> +
> +lldb::addr_t
> +ProcessElfCore::GetImageInfoAddress()
> +{
> + Target *target = &GetTarget();
> + ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
> + Address addr = obj_file->GetImageInfoAddress();
> +
> + if (addr.IsValid())
> + return addr.GetLoadAddress(target);
> + return LLDB_INVALID_ADDRESS;
> +}
> +
> +/// Core files PT_NOTE segment descriptor types
> +enum {
> + NT_PRSTATUS = 1,
> + NT_FPREGSET,
> + NT_PRPSINFO,
> + NT_TASKSTRUCT,
> + NT_PLATFORM,
> + NT_AUXV
> +};
> +
> +/// Note Structure found in ELF core dumps.
> +/// This is PT_NOTE type program/segments in the core file.
> +struct ELFNote
> +{
> + elf::elf_word n_namesz;
> + elf::elf_word n_descsz;
> + elf::elf_word n_type;
> +
> + ELFNote()
> + {
> + memset(this, 0, sizeof(ELFNote));
> + }
> +
> + /// Parse an ELFNote entry from the given DataExtractor starting at position
> + /// \p offset.
> + ///
> + /// @param[in] data
> + /// The DataExtractor to read from.
> + ///
> + /// @param[in,out] offset
> + /// Pointer to an offset in the data. On return the offset will be
> + /// advanced by the number of bytes read.
> + ///
> + /// @return
> + /// True if the ELFRel entry was successfully read and false otherwise.
> + bool
> + Parse(const DataExtractor &data, lldb::offset_t *offset)
> + {
> + // Read all fields.
> + if (!data.GetU32(offset, &n_namesz, 3))
> + return false;
> +
> + return true;
> + }
> +};
> +
> +/// Align the given value to next boundary specified by the alignment bytes
> +static uint32_t
> +AlignToNext(uint32_t value, int alignment_bytes)
> +{
> + return (value + alignment_bytes - 1) & ~(alignment_bytes - 1);
> +}
> +
> +/// Parse Thread context from PT_NOTE segment and store it in the thread list
> +/// Notes:
> +/// 1) A PT_NOTE segment is composed of one or more NOTE entries.
> +/// 2) NOTE Entry contains a standard header followed by variable size data.
> +/// (see ELFNote structure)
> +/// 3) A Thread Context in a core file usually described by 3 NOTE entries.
> +/// a) NT_PRSTATUS - Register context
> +/// b) NT_PRPSINFO - Process info(pid..)
> +/// c) NT_FPREGSET - Floating point registers
> +/// 4) The NOTE entries can be in any order
> +/// 5) If a core file contains multiple thread contexts then there is two data forms
> +/// a) Each thread context(2 or more NOTE entries) contained in its own segment (PT_NOTE)
> +/// b) All thread context is stored in a single segment(PT_NOTE).
> +/// This case is little tricker since while parsing we have to find where the
> +/// new thread starts. The current implementation marks begining of
> +/// new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.
> +void
> +ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *segment_header,
> + DataExtractor segment_data)
> +{
> + assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
> +
> + lldb::offset_t offset = 0;
> + ThreadData *thread_data = NULL;
> +
> + // Loop through the NOTE entries in the segment
> + while (offset < segment_header->p_filesz)
> + {
> + static unsigned lead_n_type = -1;
> + ELFNote note = ELFNote();
> + note.Parse(segment_data, &offset);
> +
> + if ((lead_n_type == (unsigned)-1) &&
> + ((note.n_type == NT_PRSTATUS) || (note.n_type == NT_PRPSINFO)))
> + lead_n_type = note.n_type;
> +
> + // Begining of new thread
> + if (note.n_type == lead_n_type)
> + {
> + if (thread_data)
> + {
> + assert(thread_data->prstatus.GetByteSize() > 0);
> + // Add the new thread to thread list
> + m_thread_data.push_back(*thread_data);
> + }
> + thread_data = new ThreadData();
> + }
> +
> + size_t note_start, note_size;
> + note_start = offset + AlignToNext(note.n_namesz, 4);
> + note_size = AlignToNext(note.n_descsz, 4);
> +
> + // Store the NOTE information in the current thread
> + DataExtractor note_data (segment_data, note_start, note_size);
> + switch (note.n_type)
> + {
> + case NT_PRSTATUS:
> + thread_data->prstatus = note_data;
> + break;
> + case NT_FPREGSET:
> + thread_data->fpregset = note_data;
> + break;
> + case NT_PRPSINFO:
> + thread_data->prpsinfo = note_data;
> + break;
> + case NT_AUXV:
> + m_auxv = DataExtractor(note_data);
> + break;
> + default:
> + break;
> + }
> +
> + offset += AlignToNext(note.n_namesz, 4) + note_size;
> + }
> + // Add last entry in the note section
> + if (thread_data && thread_data->prstatus.GetByteSize() > 0)
> + {
> + m_thread_data.push_back(*thread_data);
> + }
> +}
> +
> +uint32_t
> +ProcessElfCore::GetNumThreadContexts ()
> +{
> + if (!m_thread_data_valid)
> + DoLoadCore();
> + return m_thread_data.size();
> +}
> +
> +ArchSpec
> +ProcessElfCore::GetArchitecture()
> +{
> + ObjectFileELF *core_file = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
> + ArchSpec arch;
> + core_file->GetArchitecture(arch);
> + return arch;
> +}
> +
> +const lldb::DataBufferSP
> +ProcessElfCore::GetAuxvData()
> +{
> + const uint8_t *start = m_auxv.GetDataStart();
> + size_t len = m_auxv.GetByteSize();
> + lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
> + return buffer;
> +}
> +
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,180 @@
> +//===-- ProcessElfCore.h ---------------------------------------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +// Notes about Linux Process core dumps:
> +// 1) Linux core dump is stored as ELF file.
> +// 2) The ELF file's PT_NOTE and PT_LOAD segments describes the program's
> +// address space and thread contexts.
> +// 3) PT_NOTE segment contains note entries which describes a thread context.
> +// 4) PT_LOAD segment describes a valid contigous range of process address
> +// space.
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef liblldb_ProcessElfCore_h_
> +#define liblldb_ProcessElfCore_h_
> +
> +// C++ Includes
> +#include <list>
> +#include <vector>
> +
> +// Other libraries and framework includes
> +#include "lldb/Core/ConstString.h"
> +#include "lldb/Core/Error.h"
> +#include "lldb/Target/Process.h"
> +
> +#include "Plugins/ObjectFile/ELF/ELFHeader.h"
> +
> +class ProcessElfCore : public lldb_private::Process
> +{
> +public:
> + //------------------------------------------------------------------
> + // Constructors and Destructors
> + //------------------------------------------------------------------
> + static lldb::ProcessSP
> + CreateInstance (lldb_private::Target& target,
> + lldb_private::Listener &listener,
> + const lldb_private::FileSpec *crash_file_path);
> +
> + static void
> + Initialize();
> +
> + static void
> + Terminate();
> +
> + static lldb_private::ConstString
> + GetPluginNameStatic();
> +
> + static const char *
> + GetPluginDescriptionStatic();
> +
> + //------------------------------------------------------------------
> + // Constructors and Destructors
> + //------------------------------------------------------------------
> + ProcessElfCore(lldb_private::Target& target,
> + lldb_private::Listener &listener,
> + const lldb_private::FileSpec &core_file);
> +
> + virtual
> + ~ProcessElfCore();
> +
> + //------------------------------------------------------------------
> + // Check if a given Process
> + //------------------------------------------------------------------
> + virtual bool
> + CanDebug (lldb_private::Target &target,
> + bool plugin_specified_by_name);
> +
> + //------------------------------------------------------------------
> + // Creating a new process, or attaching to an existing one
> + //------------------------------------------------------------------
> + virtual lldb_private::Error
> + DoLoadCore ();
> +
> + virtual lldb_private::DynamicLoader *
> + GetDynamicLoader ();
> +
> + //------------------------------------------------------------------
> + // PluginInterface protocol
> + //------------------------------------------------------------------
> + virtual lldb_private::ConstString
> + GetPluginName();
> +
> + virtual uint32_t
> + GetPluginVersion();
> +
> + //------------------------------------------------------------------
> + // Process Control
> + //------------------------------------------------------------------
> + virtual lldb_private::Error
> + DoDestroy ();
> +
> + virtual void
> + RefreshStateAfterStop();
> +
> + //------------------------------------------------------------------
> + // Process Queries
> + //------------------------------------------------------------------
> + virtual bool
> + IsAlive ();
> +
> + //------------------------------------------------------------------
> + // Process Memory
> + //------------------------------------------------------------------
> + virtual size_t
> + ReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error);
> +
> + virtual size_t
> + DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error);
> +
> + virtual lldb::addr_t
> + GetImageInfoAddress ();
> +
> + lldb_private::ArchSpec
> + GetArchitecture();
> +
> + // Returns AUXV structure found in the core file
> + const lldb::DataBufferSP
> + GetAuxvData();
> +
> +protected:
> + friend class ThreadElfCore;
> +
> + void
> + Clear ( );
> +
> + virtual bool
> + UpdateThreadList (lldb_private::ThreadList &old_thread_list,
> + lldb_private::ThreadList &new_thread_list);
> +
> +private:
> + //------------------------------------------------------------------
> + // For ProcessElfCore only
> + //------------------------------------------------------------------
> + typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
> + typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
> +
> + // In ELF core file thread context is described mainly by 3 Note entries
> + // The following structure holds pointers to those note entries.
> + struct ThreadData
> + {
> + lldb_private::DataExtractor prstatus;
> + lldb_private::DataExtractor fpregset;
> + lldb_private::DataExtractor prpsinfo;
> + };
> +
> + lldb::ModuleSP m_core_module_sp;
> + lldb_private::FileSpec m_core_file;
> + std::string m_dyld_plugin_name;
> + DISALLOW_COPY_AND_ASSIGN (ProcessElfCore);
> +
> + // True if m_thread_contexts contains valid entries
> + bool m_thread_data_valid;
> +
> + // Contain thread data read from NOTE segments
> + std::vector<ThreadData> m_thread_data;
> +
> + // AUXV structure found from the NOTE segment
> + lldb_private::DataExtractor m_auxv;
> +
> + // Address ranges found in the core
> + VMRangeToFileOffset m_core_aranges;
> +
> + // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
> + void
> + ParseThreadContextsFromNoteSegment (const elf::ELFProgramHeader *segment_header,
> + lldb_private::DataExtractor segment_data);
> +
> + // Returns number of thread contexts stored in the core file
> + uint32_t
> + GetNumThreadContexts();
> +
> + // Parse a contiguous address range of the process from LOAD segment
> + lldb::addr_t
> + AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header);
> +};
> +
> +#endif // liblldb_ProcessElffCore_h_
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.cpp?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.cpp (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.cpp Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,68 @@
> +//===-- RegisterContextCoreFreeBSD_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 "lldb/Core/DataExtractor.h"
> +#include "lldb/Core/RegisterValue.h"
> +#include "lldb/Target/Thread.h"
> +#include "RegisterContextCoreFreeBSD_x86_64.h"
> +
> +RegisterContextCoreFreeBSD_x86_64::RegisterContextCoreFreeBSD_x86_64(Thread &thread,
> + const DataExtractor &gpregset, const DataExtractor &fpregset)
> + : RegisterContextFreeBSD_x86_64(thread, 0)
> +{
> + size_t size, len;
> +
> + size = GetGPRSize();
> + m_gpregset = new uint8_t[size];
> + len = gpregset.ExtractBytes(0, size, lldb::eByteOrderLittle, m_gpregset);
> + assert(len == size);
> +}
> +
> +RegisterContextCoreFreeBSD_x86_64::~RegisterContextCoreFreeBSD_x86_64()
> +{
> + delete [] m_gpregset;
> +}
> +
> +bool
> +RegisterContextCoreFreeBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
> +{
> + value = *(uint64_t *)(m_gpregset + reg_info->byte_offset);
> + return true;
> +}
> +
> +bool
> +RegisterContextCoreFreeBSD_x86_64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
> +{
> + return false;
> +}
> +
> +bool
> +RegisterContextCoreFreeBSD_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
> +{
> + return false;
> +}
> +
> +bool
> +RegisterContextCoreFreeBSD_x86_64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
> +{
> + return false;
> +}
> +
> +bool
> +RegisterContextCoreFreeBSD_x86_64::UpdateAfterBreakpoint()
> +{
> + return false;
> +}
> +
> +bool
> +RegisterContextCoreFreeBSD_x86_64::HardwareSingleStep(bool enable)
> +{
> + return false;
> +}
> +
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.h?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.h (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreFreeBSD_x86_64.h Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,47 @@
> +//===-- RegisterContextCoreFreeBSD_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_RegisterContextCoreFreeBSD_x86_64_H_
> +#define liblldb_RegisterContextCoreFreeBSD_x86_64_H_
> +
> +#include "Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h"
> +
> +using namespace lldb_private;
> +
> +class RegisterContextCoreFreeBSD_x86_64: public RegisterContextFreeBSD_x86_64
> +{
> +public:
> + RegisterContextCoreFreeBSD_x86_64 (Thread &thread, const DataExtractor &gpregset,
> + const DataExtractor &fpregset);
> +
> + ~RegisterContextCoreFreeBSD_x86_64();
> +
> + virtual bool
> + ReadRegister(const RegisterInfo *reg_info, RegisterValue &value);
> +
> + bool
> + ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
> +
> + virtual bool
> + WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value);
> +
> + bool
> + WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
> +
> + bool
> + HardwareSingleStep(bool enable);
> +
> + bool
> + UpdateAfterBreakpoint();
> +
> +private:
> + uint8_t *m_gpregset;
> +};
> +
> +#endif // #ifndef liblldb_RegisterContextCoreFreeBSD_x86_64_H_
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.cpp?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.cpp (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.cpp Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,69 @@
> +//===-- RegisterContextCoreLinux_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 "lldb/Core/DataExtractor.h"
> +#include "lldb/Core/RegisterValue.h"
> +#include "lldb/Target/Thread.h"
> +#include "RegisterContextCoreLinux_x86_64.h"
> +
> +RegisterContextCoreLinux_x86_64::RegisterContextCoreLinux_x86_64(Thread &thread,
> + const DataExtractor &gpregset,
> + const DataExtractor &fpregset)
> + : RegisterContextLinux_x86_64(thread, 0)
> +{
> + size_t size, len;
> +
> + size = GetGPRSize();
> + m_gpregset = new uint8_t[size];
> + len = gpregset.ExtractBytes(0, size, lldb::eByteOrderLittle, m_gpregset);
> + assert(len == size);
> +}
> +
> +RegisterContextCoreLinux_x86_64::~RegisterContextCoreLinux_x86_64()
> +{
> + delete [] m_gpregset;
> +}
> +
> +bool
> +RegisterContextCoreLinux_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
> +{
> + value = *(uint64_t *)(m_gpregset + reg_info->byte_offset);
> + return true;
> +}
> +
> +bool
> +RegisterContextCoreLinux_x86_64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
> +{
> + return false;
> +}
> +
> +bool
> +RegisterContextCoreLinux_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
> +{
> + return false;
> +}
> +
> +bool
> +RegisterContextCoreLinux_x86_64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
> +{
> + return false;
> +}
> +
> +bool
> +RegisterContextCoreLinux_x86_64::UpdateAfterBreakpoint()
> +{
> + return false;
> +}
> +
> +bool
> +RegisterContextCoreLinux_x86_64::HardwareSingleStep(bool enable)
> +{
> + return false;
> +}
> +
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.h?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.h (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/RegisterContextCoreLinux_x86_64.h Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,54 @@
> +//===-- RegisterContextCoreLinux_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_RegisterContextCoreLinux_x86_64_H_
> +#define liblldb_RegisterContextCoreLinux_x86_64_H_
> +
> +#include "Plugins/Process/POSIX/RegisterContextLinux_x86_64.h"
> +
> +using namespace lldb_private;
> +
> +class RegisterContextCoreLinux_x86_64: public RegisterContextLinux_x86_64
> +{
> +public:
> + RegisterContextCoreLinux_x86_64 (Thread &thread, const DataExtractor &gpregset,
> + const DataExtractor &fpregset);
> +
> + ~RegisterContextCoreLinux_x86_64();
> +
> + virtual bool
> + ReadRegister(const RegisterInfo *reg_info, RegisterValue &value);
> +
> + bool
> + ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
> +
> + virtual bool
> + WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value);
> +
> + bool
> + WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
> +
> + bool
> + HardwareSingleStep(bool enable);
> +
> + bool
> + UpdateAfterBreakpoint();
> +
> +protected:
> + bool
> + ReadFPR()
> + {
> + assert(0);
> + }
> +
> +private:
> + uint8_t *m_gpregset;
> +};
> +
> +#endif // #ifndef liblldb_RegisterContextCoreLinux_x86_64_H_
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,170 @@
> +//===-- ThreadElfCore.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/RegisterContext.h"
> +#include "lldb/Target/StopInfo.h"
> +#include "lldb/Target/Target.h"
> +#include "lldb/Target/Unwind.h"
> +#include "ProcessPOSIXLog.h"
> +
> +#include "ThreadElfCore.h"
> +#include "ProcessElfCore.h"
> +#include "RegisterContextCoreLinux_x86_64.h"
> +
> +using namespace lldb;
> +using namespace lldb_private;
> +
> +//----------------------------------------------------------------------
> +// Construct a Thread object with given PRSTATUS, PRPSINFO and FPREGSET
> +//----------------------------------------------------------------------
> +ThreadElfCore::ThreadElfCore (Process &process, tid_t tid, DataExtractor prstatus,
> + DataExtractor prpsinfo, DataExtractor fpregset) :
> + Thread(process, tid),
> + m_thread_reg_ctx_sp ()
> +{
> + ProcessElfCore *pr = static_cast<ProcessElfCore *>(GetProcess().get());
> + ArchSpec arch = pr->GetArchitecture();
> +
> + /* Parse the datastructures from the file */
> + m_prstatus.Parse(prstatus, arch);
> + m_prpsinfo.Parse(prpsinfo, arch);
> +
> + m_prstatus_data = prstatus;
> + m_fpregset_data = fpregset;
> +
> + m_thread_name = std::string(m_prpsinfo.pr_fname);
> +}
> +
> +ThreadElfCore::~ThreadElfCore ()
> +{
> + DestroyThread();
> +}
> +
> +void
> +ThreadElfCore::RefreshStateAfterStop()
> +{
> + GetRegisterContext()->InvalidateIfNeeded (false);
> +}
> +
> +void
> +ThreadElfCore::ClearStackFrames ()
> +{
> + Unwind *unwinder = GetUnwinder ();
> + if (unwinder)
> + unwinder->Clear();
> + Thread::ClearStackFrames();
> +}
> +
> +RegisterContextSP
> +ThreadElfCore::GetRegisterContext ()
> +{
> + if (m_reg_context_sp.get() == NULL) {
> + m_reg_context_sp = CreateRegisterContextForFrame (NULL);
> + }
> + return m_reg_context_sp;
> +}
> +
> +RegisterContextSP
> +ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
> +{
> + RegisterContextSP reg_ctx_sp;
> + uint32_t concrete_frame_idx = 0;
> + Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
> +
> + if (frame)
> + concrete_frame_idx = frame->GetConcreteFrameIndex ();
> +
> + if (concrete_frame_idx == 0)
> + {
> + if (m_thread_reg_ctx_sp)
> + return m_thread_reg_ctx_sp;
> +
> + ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
> + ArchSpec arch = process->GetArchitecture();
> + size_t header_size = ELFPrStatus::GetSize(arch);
> + size_t len = m_prstatus_data.GetByteSize() - header_size;
> + DataExtractor gpregset_data = DataExtractor(m_prstatus_data, header_size, len);
> + switch (arch.GetMachine())
> + {
> + case llvm::Triple::x86_64:
> + m_thread_reg_ctx_sp.reset(new RegisterContextCoreLinux_x86_64 (*this, gpregset_data, m_fpregset_data));
> + break;
> + default:
> + if (log)
> + log->Printf ("elf-core::%s:: Architecture(%d) not supported",
> + __FUNCTION__, arch.GetMachine());
> + }
> + reg_ctx_sp = m_thread_reg_ctx_sp;
> + }
> + else if (m_unwinder_ap.get())
> + {
> + reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
> + }
> + return reg_ctx_sp;
> +}
> +
> +bool
> +ThreadElfCore::CalculateStopInfo ()
> +{
> + ProcessSP process_sp (GetProcess());
> + if (process_sp)
> + {
> + SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_prstatus.pr_cursig));
> + return true;
> + }
> + return false;
> +}
> +
> +//----------------------------------------------------------------
> +// Parse PRSTATUS from NOTE entry
> +//----------------------------------------------------------------
> +ELFPrStatus::ELFPrStatus()
> +{
> + memset(this, 0, sizeof(ELFPrStatus));
> +}
> +
> +bool
> +ELFPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
> +{
> + ByteOrder byteorder = data.GetByteOrder();
> + size_t len;
> + switch(arch.GetCore())
> + {
> + case ArchSpec::eCore_x86_64_x86_64:
> + len = data.ExtractBytes(0, ELFPRSTATUS64_SIZE, byteorder, this);
> + return len == ELFPRSTATUS64_SIZE;
> + default:
> + return false;
> + }
> +}
> +
> +//----------------------------------------------------------------
> +// Parse PRPSINFO from NOTE entry
> +//----------------------------------------------------------------
> +ELFPrPsInfo::ELFPrPsInfo()
> +{
> + memset(this, 0, sizeof(ELFPrPsInfo));
> +}
> +
> +bool
> +ELFPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
> +{
> + ByteOrder byteorder = data.GetByteOrder();
> + size_t len;
> + switch(arch.GetCore())
> + {
> + case ArchSpec::eCore_x86_64_x86_64:
> + len = data.ExtractBytes(0, ELFPRPSINFO64_SIZE, byteorder, this);
> + return len == ELFPRPSINFO64_SIZE;
> + default:
> + return false;
> + }
> +}
> +
>
> Added: lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h?rev=186207&view=auto
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h (added)
> +++ lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h Fri Jul 12 16:25:02 2013
> @@ -0,0 +1,171 @@
> +//===-- ThreadElfCore.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_ThreadElfCore_h_
> +#define liblldb_ThreadElfCore_h_
> +
> +#include <string>
> +
> +#include "lldb/Target/Thread.h"
> +#include "lldb/Core/DataExtractor.h"
> +
> +struct compat_timeval
> +{
> + int64_t tv_sec;
> + int32_t tv_usec;
> +};
> +
> +// PRSTATUS structure's size differs based on architecture.
> +// Currently parsing done only for x86-64 architecture by
> +// simply reading data from the buffer.
> +// The following macros are used to specify the size.
> +// Calculating size using sizeof() wont work because of padding.
> +#define ELFPRSTATUS64_SIZE (112)
> +#define ELFPRPSINFO64_SIZE (132)
> +
> +struct ELFPrStatus
> +{
> + int32_t si_signo;
> + int32_t si_code;
> + int32_t si_errno;
> +
> + int16_t pr_cursig;
> +
> + uint64_t pr_sigpend;
> + uint64_t pr_sighold;
> +
> + uint32_t pr_pid;
> + uint32_t pr_ppid;
> + uint32_t pr_pgrp;
> + uint32_t pr_sid;
> +
> + compat_timeval pr_utime;
> + compat_timeval pr_stime;
> + compat_timeval pr_cutime;
> + compat_timeval pr_cstime;
> +
> + ELFPrStatus();
> +
> + bool
> + Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);
> +
> + static size_t
> + GetSize(lldb_private::ArchSpec &arch)
> + {
> + switch(arch.GetCore())
> + {
> + case lldb_private::ArchSpec::eCore_x86_64_x86_64:
> + return ELFPRSTATUS64_SIZE;
> + default:
> + return 0;
> + }
> + }
> +};
> +
> +struct ELFPrPsInfo
> +{
> + char pr_state;
> + char pr_sname;
> + char pr_zomb;
> + char pr_nice;
> + uint64_t pr_flag;
> + uint32_t pr_uid;
> + uint32_t pr_gid;
> + int32_t pr_pid;
> + int32_t pr_ppid;
> + int32_t pr_pgrp;
> + int32_t pr_sid;
> + char pr_fname[16];
> + char pr_psargs[80];
> +
> + ELFPrPsInfo();
> +
> + bool
> + Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);
> +
> + static size_t
> + GetSize(lldb_private::ArchSpec &arch)
> + {
> + switch(arch.GetCore())
> + {
> + case lldb_private::ArchSpec::eCore_x86_64_x86_64:
> + return ELFPRPSINFO64_SIZE;
> + default:
> + return 0;
> + }
> + }
> +
> +};
> +
> +class ThreadElfCore : public lldb_private::Thread
> +{
> +public:
> + ThreadElfCore (lldb_private::Process &process, lldb::tid_t tid,
> + lldb_private::DataExtractor prstatus,
> + lldb_private::DataExtractor prpsinfo,
> + lldb_private::DataExtractor fpregset);
> +
> + virtual
> + ~ThreadElfCore ();
> +
> + virtual void
> + RefreshStateAfterStop();
> +
> + virtual lldb::RegisterContextSP
> + GetRegisterContext ();
> +
> + virtual lldb::RegisterContextSP
> + CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
> +
> + virtual void
> + ClearStackFrames ();
> +
> + static bool
> + ThreadIDIsValid (lldb::tid_t thread)
> + {
> + return thread != 0;
> + }
> +
> + virtual const char *
> + GetName ()
> + {
> + if (m_thread_name.empty())
> + return NULL;
> + return m_thread_name.c_str();
> + }
> +
> + void
> + SetName (const char *name)
> + {
> + if (name && name[0])
> + m_thread_name.assign (name);
> + else
> + m_thread_name.clear();
> + }
> +
> +protected:
> +
> + friend class ProcessElfCore;
> +
> + //------------------------------------------------------------------
> + // Member variables.
> + //------------------------------------------------------------------
> + std::string m_thread_name;
> + lldb::RegisterContextSP m_thread_reg_ctx_sp;
> +
> + ELFPrStatus m_prstatus;
> + ELFPrPsInfo m_prpsinfo;
> + lldb_private::DataExtractor m_prstatus_data;
> + lldb_private::DataExtractor m_fpregset_data;
> +
> + virtual bool CalculateStopInfo();
> +
> +};
> +
> +#endif // liblldb_ThreadElfCore_h_
>
> Modified: lldb/trunk/source/lldb.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=186207&r1=186206&r2=186207&view=diff
> ==============================================================================
> --- lldb/trunk/source/lldb.cpp (original)
> +++ lldb/trunk/source/lldb.cpp Fri Jul 12 16:25:02 2013
> @@ -61,6 +61,7 @@
> #endif
>
> #include "Plugins/Process/mach-core/ProcessMachCore.h"
> +#include "Plugins/Process/elf-core/ProcessElfCore.h"
>
> #if defined (__linux__)
> #include "Plugins/Process/Linux/ProcessLinux.h"
> @@ -145,6 +146,7 @@ lldb_private::Initialize ()
> //----------------------------------------------------------------------
> // Platform agnostic plugins
> //----------------------------------------------------------------------
> + ProcessElfCore::Initialize();
> PlatformRemoteGDBServer::Initialize ();
> ProcessGDBRemote::Initialize();
> DynamicLoaderStatic::Initialize();
> @@ -220,7 +222,8 @@ lldb_private::Terminate ()
> #if defined (__FreeBSD__)
> ProcessFreeBSD::Terminate();
> #endif
> -
> +
> + ProcessElfCore::Terminate();
> ProcessGDBRemote::Terminate();
> DynamicLoaderStatic::Terminate();
>
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
More information about the lldb-commits
mailing list