diff options
| author | Ed Maste <emaste@FreeBSD.org> | 2014-02-18 16:23:10 +0000 |
|---|---|---|
| committer | Ed Maste <emaste@FreeBSD.org> | 2014-02-18 16:23:10 +0000 |
| commit | 866dcdacfe59f5f448e008fe2c4cb9dfcf72b2ec (patch) | |
| tree | 95cb16075f0af1b3a05b9b84eb18dda8e6c903e9 /source/Plugins/Process/elf-core | |
| parent | de889deb2c386f2a7831befaf226e5c86685fa53 (diff) | |
Diffstat (limited to 'source/Plugins/Process/elf-core')
3 files changed, 83 insertions, 45 deletions
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 93641ede1bc78..7ea5c89e7df4f 100644 --- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -131,7 +131,8 @@ ProcessElfCore::AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *head 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->data.GetRangeEnd() == range_entry.data.GetRangeBase() && + last_entry->GetByteSize() == last_entry->data.GetByteSize()) { last_entry->SetRangeEnd (range_entry.GetRangeEnd()); last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd()); @@ -294,9 +295,13 @@ ProcessElfCore::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error & 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; + // Figure out how many on-disk bytes remain in this segment + // starting at the given offset + if (file_end > file_start + offset) + bytes_left = file_end - (file_start + offset); + // Figure out how many bytes we need to zero-fill if we are + // reading more bytes than available in the on-disk segment if (bytes_to_read > bytes_left) { zero_fill_size = bytes_to_read - bytes_left; @@ -365,12 +370,12 @@ enum { // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details. static void -ParseFreeBSDPrStatus(ThreadData *thread_data, DataExtractor &data, +ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data, ArchSpec &arch) { lldb::offset_t offset = 0; - bool have_padding = (arch.GetMachine() == llvm::Triple::mips64 || - arch.GetMachine() == llvm::Triple::x86_64); + bool lp64 = (arch.GetMachine() == llvm::Triple::mips64 || + arch.GetMachine() == llvm::Triple::x86_64); int pr_version = data.GetU32(&offset); Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); @@ -380,23 +385,26 @@ ParseFreeBSDPrStatus(ThreadData *thread_data, DataExtractor &data, log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version); } - if (have_padding) - offset += 4; - offset += 28; // pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate - thread_data->signo = data.GetU32(&offset); // pr_cursig + // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate + if (lp64) + offset += 32; + else + offset += 16; + + thread_data.signo = data.GetU32(&offset); // pr_cursig offset += 4; // pr_pid - if (have_padding) + if (lp64) offset += 4; size_t len = data.GetByteSize() - offset; - thread_data->gpregset = DataExtractor(data, offset, len); + thread_data.gpregset = DataExtractor(data, offset, len); } static void -ParseFreeBSDThrMisc(ThreadData *thread_data, DataExtractor &data) +ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data) { lldb::offset_t offset = 0; - thread_data->name = data.GetCStr(&offset, 20); + thread_data.name = data.GetCStr(&offset, 20); } /// Parse Thread context from PT_NOTE segment and store it in the thread list @@ -418,13 +426,13 @@ ParseFreeBSDThrMisc(ThreadData *thread_data, DataExtractor &data) /// 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). void -ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *segment_header, +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 = new ThreadData(); + std::unique_ptr<ThreadData> thread_data(new ThreadData); bool have_prstatus = false; bool have_prpsinfo = false; @@ -447,7 +455,7 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader * assert(thread_data->gpregset.GetByteSize() > 0); // Add the new thread to thread list m_thread_data.push_back(*thread_data); - thread_data = new ThreadData(); + *thread_data = ThreadData(); have_prstatus = false; have_prpsinfo = false; } @@ -464,7 +472,7 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader * { case NT_FREEBSD_PRSTATUS: have_prstatus = true; - ParseFreeBSDPrStatus(thread_data, note_data, arch); + ParseFreeBSDPrStatus(*thread_data, note_data, arch); break; case NT_FREEBSD_FPREGSET: thread_data->fpregset = note_data; @@ -473,7 +481,7 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader * have_prpsinfo = true; break; case NT_FREEBSD_THRMISC: - ParseFreeBSDThrMisc(thread_data, note_data); + ParseFreeBSDThrMisc(*thread_data, note_data); break; case NT_FREEBSD_PROCSTAT_AUXV: // FIXME: FreeBSD sticks an int at the beginning of the note diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index 610506c20a0bd..3e09c7bc20322 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -63,8 +63,16 @@ RegisterContextCorePOSIX_x86_64::WriteFPR() bool RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { - value = *(uint64_t *)(m_gpregset + reg_info->byte_offset); - return true; + switch (reg_info->byte_size) + { + case 4: + value = *(uint32_t *)(m_gpregset + reg_info->byte_offset); + return true; + case 8: + value = *(uint64_t *)(m_gpregset + reg_info->byte_offset); + return true; + } + return false; } bool diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 3bda86dc0f739..cadcf53ca5431 100644 --- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -17,6 +17,7 @@ #include "ThreadElfCore.h" #include "ProcessElfCore.h" #include "RegisterContextLinux_x86_64.h" +#include "RegisterContextFreeBSD_i386.h" #include "RegisterContextFreeBSD_mips64.h" #include "RegisterContextFreeBSD_x86_64.h" #include "RegisterContextPOSIXCore_mips64.h" @@ -85,45 +86,66 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get()); ArchSpec arch = process->GetArchitecture(); - switch (arch.GetMachine()) + RegisterInfoInterface *reg_interface = NULL; + + switch (arch.GetTriple().getOS()) { - case llvm::Triple::mips64: - switch (arch.GetTriple().getOS()) + case llvm::Triple::FreeBSD: + { + switch (arch.GetMachine()) { - case llvm::Triple::FreeBSD: - m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, new RegisterContextFreeBSD_mips64(arch), m_gpregset_data, m_fpregset_data)); + case llvm::Triple::mips64: + reg_interface = new RegisterContextFreeBSD_mips64(arch); + break; + case llvm::Triple::x86: + reg_interface = new RegisterContextFreeBSD_i386(arch); + break; + case llvm::Triple::x86_64: + reg_interface = new RegisterContextFreeBSD_x86_64(arch); break; default: - if (log) - log->Printf ("elf-core::%s:: OS(%d) not supported", - __FUNCTION__, arch.GetTriple().getOS()); - assert (false && "OS not supported"); break; } break; - case llvm::Triple::x86_64: - switch (arch.GetTriple().getOS()) + } + + case llvm::Triple::Linux: + { + switch (arch.GetMachine()) { - case llvm::Triple::FreeBSD: - m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, new RegisterContextFreeBSD_x86_64(arch), m_gpregset_data, m_fpregset_data)); - break; - case llvm::Triple::Linux: - m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, new RegisterContextLinux_x86_64(arch), m_gpregset_data, m_fpregset_data)); + case llvm::Triple::x86_64: + reg_interface = new RegisterContextLinux_x86_64(arch); break; default: - if (log) - log->Printf ("elf-core::%s:: OS(%d) not supported", - __FUNCTION__, arch.GetTriple().getOS()); - assert (false && "OS not supported"); break; } break; + } + + default: + break; + } + + if (!reg_interface) { + if (log) + log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported", + __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); + assert (false && "Architecture or OS not supported"); + } + + switch (arch.GetMachine()) + { + case llvm::Triple::mips64: + m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); + break; default: - if (log) - log->Printf ("elf-core::%s:: Architecture(%d) not supported", - __FUNCTION__, arch.GetMachine()); - assert (false && "Architecture not supported"); + break; } + reg_ctx_sp = m_thread_reg_ctx_sp; } else if (m_unwinder_ap.get()) |
