[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