diff options
Diffstat (limited to 'source/Plugins/Process/elf-core')
7 files changed, 105 insertions, 56 deletions
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 7ea5c89e7df4..566816783c7e 100644 --- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -17,12 +17,17 @@ #include "lldb/Core/Section.h" #include "lldb/Core/State.h" #include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/Log.h" #include "lldb/Target/Target.h" #include "lldb/Target/DynamicLoader.h" -#include "ProcessPOSIXLog.h" +#include "lldb/Target/UnixSignals.h" + +#include "llvm/Support/ELF.h" #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" +#include "Plugins/Process/Utility/FreeBSDSignals.h" +#include "Plugins/Process/Utility/LinuxSignals.h" // Project includes #include "ProcessElfCore.h" @@ -54,8 +59,25 @@ 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)); + if (crash_file) + { + // Read enough data for a ELF32 header or ELF64 header + const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr); + + lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size)); + if (data_sp && data_sp->GetByteSize() == header_size && + elf::ELFHeader::MagicBytesMatch (data_sp->GetBytes())) + { + elf::ELFHeader elf_header; + DataExtractor data(data_sp, lldb::eByteOrderLittle, 4); + lldb::offset_t data_offset = 0; + if (elf_header.Parse(data, &data_offset)) + { + if (elf_header.e_type == llvm::ELF::ET_CORE) + process_sp.reset(new ProcessElfCore (target, listener, *crash_file)); + } + } + } return process_sp; } @@ -66,7 +88,7 @@ ProcessElfCore::CanDebug(Target &target, bool plugin_specified_by_name) 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, + Error error (ModuleList::GetSharedModule (core_module_spec, m_core_module_sp, NULL, NULL, NULL)); if (m_core_module_sp) { @@ -87,6 +109,7 @@ ProcessElfCore::ProcessElfCore(Target& target, Listener &listener, m_core_module_sp (), m_core_file (core_file), m_dyld_plugin_name (), + m_os(llvm::Triple::UnknownOS), m_thread_data_valid(false), m_thread_data(), m_core_aranges () @@ -154,21 +177,21 @@ ProcessElfCore::DoLoadCore () Error error; if (!m_core_module_sp) { - error.SetErrorString ("invalid core module"); + error.SetErrorString ("invalid core module"); return error; } ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile()); if (core == NULL) { - error.SetErrorString ("invalid core object file"); + 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"); + error.SetErrorString ("core file has no sections"); return error; } @@ -209,7 +232,25 @@ ProcessElfCore::DoLoadCore () // it to match the core file which is always single arch. ArchSpec arch (m_core_module_sp->GetArchitecture()); if (arch.IsValid()) - m_target.SetArchitecture(arch); + m_target.SetArchitecture(arch); + + switch (m_os) + { + case llvm::Triple::FreeBSD: + { + static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals ()); + SetUnixSignals(s_freebsd_signals_sp); + break; + } + case llvm::Triple::Linux: + { + static UnixSignalsSP s_linux_signals_sp(new process_linux::LinuxSignals ()); + SetUnixSignals(s_linux_signals_sp); + break; + } + default: + break; + } return error; } @@ -324,13 +365,17 @@ void ProcessElfCore::Clear() { m_thread_list.Clear(); + m_os = llvm::Triple::UnknownOS; + + static UnixSignalsSP s_default_unix_signals_sp(new UnixSignals()); + SetUnixSignals(s_default_unix_signals_sp); } void ProcessElfCore::Initialize() { static bool g_initialized = false; - + if (g_initialized == false) { g_initialized = true; @@ -378,7 +423,7 @@ ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data, arch.GetMachine() == llvm::Triple::x86_64); int pr_version = data.GetU32(&offset); - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); + Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); if (log) { if (pr_version > 1) @@ -395,7 +440,7 @@ ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data, offset += 4; // pr_pid if (lp64) offset += 4; - + size_t len = data.GetByteSize() - offset; thread_data.gpregset = DataExtractor(data, offset, len); } @@ -421,7 +466,7 @@ ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data) /// 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 beginning of +/// new thread starts. The current implementation marks beginning of /// new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry. /// For case (b) there may be either one NT_PRPSINFO per thread, or a single /// one that applies to all threads (depending on the platform type). @@ -468,6 +513,7 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader * DataExtractor note_data (segment_data, note_start, note_size); if (note.n_name == "FreeBSD") { + m_os = llvm::Triple::FreeBSD; switch (note.n_type) { case NT_FREEBSD_PRSTATUS: @@ -553,4 +599,3 @@ ProcessElfCore::GetAuxvData() lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len)); return buffer; } - diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.h b/source/Plugins/Process/elf-core/ProcessElfCore.h index 1c1ed98ce17a..2fc2e4ee7949 100644 --- a/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -37,45 +37,45 @@ public: // Constructors and Destructors //------------------------------------------------------------------ static lldb::ProcessSP - CreateInstance (lldb_private::Target& target, - lldb_private::Listener &listener, + 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, + 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 (); @@ -84,19 +84,19 @@ public: //------------------------------------------------------------------ virtual lldb_private::ConstString GetPluginName(); - + virtual uint32_t GetPluginVersion(); - + //------------------------------------------------------------------ // Process Control - //------------------------------------------------------------------ + //------------------------------------------------------------------ virtual lldb_private::Error DoDestroy (); - + virtual void RefreshStateAfterStop(); - + //------------------------------------------------------------------ // Process Queries //------------------------------------------------------------------ @@ -108,10 +108,10 @@ public: //------------------------------------------------------------------ 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 (); @@ -120,16 +120,16 @@ public: // Returns AUXV structure found in the core file const lldb::DataBufferSP - GetAuxvData(); + GetAuxvData() override; protected: void Clear ( ); - + virtual bool - UpdateThreadList (lldb_private::ThreadList &old_thread_list, + UpdateThreadList (lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list); - + private: //------------------------------------------------------------------ // For ProcessElfCore only @@ -142,6 +142,8 @@ private: std::string m_dyld_plugin_name; DISALLOW_COPY_AND_ASSIGN (ProcessElfCore); + llvm::Triple::OSType m_os; + // True if m_thread_contexts contains valid entries bool m_thread_data_valid; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index b95a51130ca7..fbf397b933cc 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -21,13 +21,9 @@ RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(Thread &thread, const DataExtractor &fpregset) : RegisterContextPOSIX_mips64(thread, 0, register_info) { - size_t i; - lldb::offset_t offset = 0; - - for (i = 0; i < k_num_gpr_registers_mips64; i++) - { - m_reg[i] = gpregset.GetU64(&offset); - } + m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); + m_gpr.SetData(m_gpr_buffer); + m_gpr.SetByteOrder(gpregset.GetByteOrder()); } RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() @@ -63,10 +59,14 @@ RegisterContextCorePOSIX_mips64::WriteFPR() bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { - int reg_num = reg_info->byte_offset / 8; - assert(reg_num < k_num_gpr_registers_mips64); - value = m_reg[reg_num]; - return true; + lldb::offset_t offset = reg_info->byte_offset; + uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); + if (offset == reg_info->byte_offset + reg_info->byte_size) + { + value = v; + return true; + } + return false; } bool diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h index 92e486bf2235..ca29d4f0febd 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h @@ -10,14 +10,15 @@ #ifndef liblldb_RegisterContextCorePOSIX_mips64_H_ #define liblldb_RegisterContextCorePOSIX_mips64_H_ -#include "Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h" +#include "lldb/Core/DataBufferHeap.h" +#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" class RegisterContextCorePOSIX_mips64 : public RegisterContextPOSIX_mips64 { public: RegisterContextCorePOSIX_mips64 (lldb_private::Thread &thread, - RegisterInfoInterface *register_info, + lldb_private::RegisterInfoInterface *register_info, const lldb_private::DataExtractor &gpregset, const lldb_private::DataExtractor &fpregset); @@ -52,7 +53,8 @@ protected: WriteFPR(); private: - uint64_t m_reg[40]; + lldb::DataBufferSP m_gpr_buffer; + lldb_private::DataExtractor m_gpr; }; #endif // #ifndef liblldb_RegisterContextCorePOSIX_mips64_H_ diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h index d4ea14fab7b1..ac0f49c3db52 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h @@ -10,14 +10,14 @@ #ifndef liblldb_RegisterContextCorePOSIX_x86_64_H_ #define liblldb_RegisterContextCorePOSIX_x86_64_H_ -#include "Plugins/Process/POSIX/RegisterContextPOSIX_x86.h" +#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h" class RegisterContextCorePOSIX_x86_64 : public RegisterContextPOSIX_x86 { public: RegisterContextCorePOSIX_x86_64 (lldb_private::Thread &thread, - RegisterInfoInterface *register_info, + lldb_private::RegisterInfoInterface *register_info, const lldb_private::DataExtractor &gpregset, const lldb_private::DataExtractor &fpregset); diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp index cadcf53ca543..d9f6cc04a343 100644 --- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -8,11 +8,11 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Log.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" @@ -74,7 +74,7 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) { RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); + Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex (); @@ -108,7 +108,7 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) } break; } - + case llvm::Triple::Linux: { switch (arch.GetMachine()) diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.h b/source/Plugins/Process/elf-core/ThreadElfCore.h index 2661edfa50cd..f1f00cf019b3 100644 --- a/source/Plugins/Process/elf-core/ThreadElfCore.h +++ b/source/Plugins/Process/elf-core/ThreadElfCore.h @@ -40,7 +40,7 @@ struct ELFLinuxPrStatus int32_t si_errno; int16_t pr_cursig; - + uint64_t pr_sigpend; uint64_t pr_sighold; |