diff options
| author | Nitesh Jain <nitesh.jain@imgtec.com> | 2017-03-31 11:14:02 +0000 |
|---|---|---|
| committer | Nitesh Jain <nitesh.jain@imgtec.com> | 2017-03-31 11:14:02 +0000 |
| commit | b8dbd323758bbffb55cdb63600e18f876b2a51aa (patch) | |
| tree | 680b105e3fbc73c378d421d412a6fe1f9e2c1c51 /lldb/source/Plugins/Process/elf-core | |
| parent | 706c5205584acc65b1140968e6197165f525c487 (diff) | |
| download | bcm5719-llvm-b8dbd323758bbffb55cdb63600e18f876b2a51aa.tar.gz bcm5719-llvm-b8dbd323758bbffb55cdb63600e18f876b2a51aa.zip | |
[LLDB][MIPS] Core Dump Support.
Reviewers: labath, emaste
Subscribers: jaydeep, bhushan, lldb-commits, slthakur
Differential Revision: https://reviews.llvm.org/D30457
llvm-svn: 299200
Diffstat (limited to 'lldb/source/Plugins/Process/elf-core')
4 files changed, 107 insertions, 39 deletions
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index 6a168d314fd..7549cf074be 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -22,6 +22,10 @@ RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64( new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); m_gpr.SetData(m_gpr_buffer); m_gpr.SetByteOrder(gpregset.GetByteOrder()); + m_fpr_buffer.reset( + new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize())); + m_fpr.SetData(m_fpr_buffer); + m_fpr.SetByteOrder(fpregset.GetByteOrder()); } RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() {} @@ -42,12 +46,24 @@ bool RegisterContextCorePOSIX_mips64::WriteFPR() { bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { + 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) { + lldb_private::ArchSpec arch = m_register_info_ap->GetTargetArchitecture(); + uint64_t v; + if (IsGPR(reg_info->kinds[lldb::eRegisterKindLLDB])) { + if (reg_info->byte_size == 4 && !(arch.GetMachine() == llvm::Triple::mips64el)) + // In case of 32bit core file, the register data are placed at 4 byte + // offset. + offset = offset / 2; + v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); value = v; return true; - } + } else if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) { + offset = offset - sizeof(GPR_linux_mips); + v =m_fpr.GetMaxU64(&offset, reg_info->byte_size); + value = v; + return true; + } return false; } diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h index d1f38f037f1..2cb527a8de7 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h @@ -51,7 +51,9 @@ protected: private: lldb::DataBufferSP m_gpr_buffer; + lldb::DataBufferSP m_fpr_buffer; lldb_private::DataExtractor m_gpr; + lldb_private::DataExtractor m_fpr; }; #endif // liblldb_RegisterContextCorePOSIX_mips64_h_ diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index dda41e002c3..13ad82d92c5 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -18,6 +18,8 @@ #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" +#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" +#include "Plugins/Process/Utility/RegisterContextLinux_mips.h" #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" @@ -132,6 +134,14 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { case llvm::Triple::aarch64: reg_interface = new RegisterInfoPOSIX_arm64(arch); break; + case llvm::Triple::mipsel: + case llvm::Triple::mips: + reg_interface = new RegisterContextLinux_mips(arch); + break; + case llvm::Triple::mips64el: + case llvm::Triple::mips64: + reg_interface = new RegisterContextLinux_mips64(arch); + break; case llvm::Triple::systemz: reg_interface = new RegisterContextLinux_s390x(arch); break; @@ -187,7 +197,13 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm( *this, reg_interface, m_gpregset_data, m_fpregset_data)); break; + case llvm::Triple::mipsel: + case llvm::Triple::mips: + m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( + *this, reg_interface, m_gpregset_data, m_fpregset_data)); + break; case llvm::Triple::mips64: + case llvm::Triple::mips64el: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( *this, reg_interface, m_gpregset_data, m_fpregset_data)); break; @@ -233,6 +249,31 @@ ELFLinuxPrStatus::ELFLinuxPrStatus() { memset(this, 0, sizeof(ELFLinuxPrStatus)); } +size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) { + constexpr size_t mips_linux_pr_status_size_o32 = 96; + constexpr size_t mips_linux_pr_status_size_n32 = 72; + if (arch.IsMIPS()) { + std::string abi = arch.GetTargetABI(); + assert(!abi.empty() && "ABI is not set"); + if (!abi.compare("n64")) + return sizeof(ELFLinuxPrStatus); + else if (!abi.compare("o32")) + return mips_linux_pr_status_size_o32; + // N32 ABI + return mips_linux_pr_status_size_n32; + } + switch (arch.GetCore()) { + case lldb_private::ArchSpec::eCore_s390x_generic: + case lldb_private::ArchSpec::eCore_x86_64_x86_64: + return sizeof(ELFLinuxPrStatus); + case lldb_private::ArchSpec::eCore_x86_32_i386: + case lldb_private::ArchSpec::eCore_x86_32_i486: + return 72; + default: + return 0; + } +} + Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) { Error error; if (GetSize(arch) > data.GetByteSize()) { @@ -282,6 +323,27 @@ ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); } +size_t ELFLinuxPrPsInfo::GetSize(lldb_private::ArchSpec &arch) { + constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128; + if (arch.IsMIPS()) { + uint8_t address_byte_size = arch.GetAddressByteSize(); + if (address_byte_size == 8) + return sizeof(ELFLinuxPrPsInfo); + return mips_linux_pr_psinfo_size_o32_n32; + } + + switch (arch.GetCore()) { + case lldb_private::ArchSpec::eCore_s390x_generic: + case lldb_private::ArchSpec::eCore_x86_64_x86_64: + return sizeof(ELFLinuxPrPsInfo); + case lldb_private::ArchSpec::eCore_x86_32_i386: + case lldb_private::ArchSpec::eCore_x86_32_i486: + return 124; + default: + return 0; + } +} + Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) { Error error; ByteOrder byteorder = data.GetByteOrder(); @@ -305,9 +367,15 @@ Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) { pr_flag = data.GetPointer(&offset); + if (arch.IsMIPS()) { + // The pr_uid and pr_gid is always 32 bit irrespective of platforms + pr_uid = data.GetU32(&offset); + pr_gid = data.GetU32(&offset); + } else { // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); + } pr_pid = data.GetU32(&offset); pr_ppid = data.GetU32(&offset); @@ -330,6 +398,21 @@ Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) { //---------------------------------------------------------------- ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); } +size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) { + if (arch.IsMIPS()) + return sizeof(ELFLinuxSigInfo); + switch (arch.GetCore()) { + case lldb_private::ArchSpec::eCore_x86_64_x86_64: + return sizeof(ELFLinuxSigInfo); + case lldb_private::ArchSpec::eCore_s390x_generic: + case lldb_private::ArchSpec::eCore_x86_32_i386: + case lldb_private::ArchSpec::eCore_x86_32_i486: + return 12; + default: + return 0; + } +} + Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) { Error error; if (GetSize(arch) > data.GetByteSize()) { diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h index 31cfd10b098..38c52658a23 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h @@ -65,18 +65,7 @@ struct ELFLinuxPrStatus { // 32 bit - hardcoded because we are reusing the struct, but some of the // members are smaller - // so the layout is not the same - static size_t GetSize(lldb_private::ArchSpec &arch) { - switch (arch.GetCore()) { - case lldb_private::ArchSpec::eCore_s390x_generic: - case lldb_private::ArchSpec::eCore_x86_64_x86_64: - return sizeof(ELFLinuxPrStatus); - case lldb_private::ArchSpec::eCore_x86_32_i386: - case lldb_private::ArchSpec::eCore_x86_32_i486: - return 72; - default: - return 0; - } - } + static size_t GetSize(lldb_private::ArchSpec &arch); }; static_assert(sizeof(ELFLinuxPrStatus) == 112, @@ -97,18 +86,7 @@ struct ELFLinuxSigInfo { // 32 bit - hardcoded because we are reusing the struct, but some of the // members are smaller - // so the layout is not the same - static size_t GetSize(const lldb_private::ArchSpec &arch) { - switch (arch.GetCore()) { - case lldb_private::ArchSpec::eCore_x86_64_x86_64: - return sizeof(ELFLinuxSigInfo); - case lldb_private::ArchSpec::eCore_s390x_generic: - case lldb_private::ArchSpec::eCore_x86_32_i386: - case lldb_private::ArchSpec::eCore_x86_32_i486: - return 12; - default: - return 0; - } - } + static size_t GetSize(const lldb_private::ArchSpec &arch); }; static_assert(sizeof(ELFLinuxSigInfo) == 12, @@ -143,18 +121,7 @@ struct ELFLinuxPrPsInfo { // 32 bit - hardcoded because we are reusing the struct, but some of the // members are smaller - // so the layout is not the same - static size_t GetSize(lldb_private::ArchSpec &arch) { - switch (arch.GetCore()) { - case lldb_private::ArchSpec::eCore_s390x_generic: - case lldb_private::ArchSpec::eCore_x86_64_x86_64: - return sizeof(ELFLinuxPrPsInfo); - case lldb_private::ArchSpec::eCore_x86_32_i386: - case lldb_private::ArchSpec::eCore_x86_32_i486: - return 124; - default: - return 0; - } - } + static size_t GetSize(lldb_private::ArchSpec &arch); }; static_assert(sizeof(ELFLinuxPrPsInfo) == 136, |

