ThreadElfCore.cpp revision 263363
1//===-- ThreadElfCore.cpp --------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/DataExtractor.h"
11#include "lldb/Target/RegisterContext.h"
12#include "lldb/Target/StopInfo.h"
13#include "lldb/Target/Target.h"
14#include "lldb/Target/Unwind.h"
15#include "ProcessPOSIXLog.h"
16
17#include "ThreadElfCore.h"
18#include "ProcessElfCore.h"
19#include "RegisterContextLinux_x86_64.h"
20#include "RegisterContextFreeBSD_mips64.h"
21#include "RegisterContextFreeBSD_x86_64.h"
22#include "RegisterContextPOSIXCore_mips64.h"
23#include "RegisterContextPOSIXCore_x86_64.h"
24
25using namespace lldb;
26using namespace lldb_private;
27
28//----------------------------------------------------------------------
29// Construct a Thread object with given data
30//----------------------------------------------------------------------
31ThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
32                              const ThreadData &td) :
33    Thread(process, tid),
34    m_thread_name(td.name),
35    m_thread_reg_ctx_sp (),
36    m_signo(td.signo),
37    m_gpregset_data(td.gpregset),
38    m_fpregset_data(td.fpregset)
39{
40}
41
42ThreadElfCore::~ThreadElfCore ()
43{
44    DestroyThread();
45}
46
47void
48ThreadElfCore::RefreshStateAfterStop()
49{
50    GetRegisterContext()->InvalidateIfNeeded (false);
51}
52
53void
54ThreadElfCore::ClearStackFrames ()
55{
56    Unwind *unwinder = GetUnwinder ();
57    if (unwinder)
58        unwinder->Clear();
59    Thread::ClearStackFrames();
60}
61
62RegisterContextSP
63ThreadElfCore::GetRegisterContext ()
64{
65    if (m_reg_context_sp.get() == NULL) {
66        m_reg_context_sp = CreateRegisterContextForFrame (NULL);
67    }
68    return m_reg_context_sp;
69}
70
71RegisterContextSP
72ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
73{
74    RegisterContextSP reg_ctx_sp;
75    uint32_t concrete_frame_idx = 0;
76    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
77
78    if (frame)
79        concrete_frame_idx = frame->GetConcreteFrameIndex ();
80
81    if (concrete_frame_idx == 0)
82    {
83        if (m_thread_reg_ctx_sp)
84            return m_thread_reg_ctx_sp;
85
86        ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
87        ArchSpec arch = process->GetArchitecture();
88        switch (arch.GetMachine())
89        {
90            case llvm::Triple::mips64:
91                switch (arch.GetTriple().getOS())
92                {
93                    case llvm::Triple::FreeBSD:
94                        m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, new RegisterContextFreeBSD_mips64(arch), m_gpregset_data, m_fpregset_data));
95                        break;
96                    default:
97                        if (log)
98                            log->Printf ("elf-core::%s:: OS(%d) not supported",
99                                         __FUNCTION__, arch.GetTriple().getOS());
100                        assert (false && "OS not supported");
101                        break;
102                }
103                break;
104            case llvm::Triple::x86_64:
105                switch (arch.GetTriple().getOS())
106                {
107                    case llvm::Triple::FreeBSD:
108                        m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, new RegisterContextFreeBSD_x86_64(arch), m_gpregset_data, m_fpregset_data));
109                        break;
110                    case llvm::Triple::Linux:
111                        m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, new RegisterContextLinux_x86_64(arch), m_gpregset_data, m_fpregset_data));
112                        break;
113                    default:
114                        if (log)
115                            log->Printf ("elf-core::%s:: OS(%d) not supported",
116                                         __FUNCTION__, arch.GetTriple().getOS());
117                        assert (false && "OS not supported");
118                        break;
119                }
120                break;
121            default:
122                if (log)
123                    log->Printf ("elf-core::%s:: Architecture(%d) not supported",
124                                 __FUNCTION__, arch.GetMachine());
125                assert (false && "Architecture not supported");
126        }
127        reg_ctx_sp = m_thread_reg_ctx_sp;
128    }
129    else if (m_unwinder_ap.get())
130    {
131        reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
132    }
133    return reg_ctx_sp;
134}
135
136bool
137ThreadElfCore::CalculateStopInfo ()
138{
139    ProcessSP process_sp (GetProcess());
140    if (process_sp)
141    {
142        SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
143        return true;
144    }
145    return false;
146}
147
148//----------------------------------------------------------------
149// Parse PRSTATUS from NOTE entry
150//----------------------------------------------------------------
151ELFLinuxPrStatus::ELFLinuxPrStatus()
152{
153    memset(this, 0, sizeof(ELFLinuxPrStatus));
154}
155
156bool
157ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
158{
159    ByteOrder byteorder = data.GetByteOrder();
160    size_t len;
161    switch(arch.GetCore())
162    {
163        case ArchSpec::eCore_x86_64_x86_64:
164            len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
165            return len == ELFLINUXPRSTATUS64_SIZE;
166        default:
167            return false;
168    }
169}
170
171//----------------------------------------------------------------
172// Parse PRPSINFO from NOTE entry
173//----------------------------------------------------------------
174ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
175{
176    memset(this, 0, sizeof(ELFLinuxPrPsInfo));
177}
178
179bool
180ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
181{
182    ByteOrder byteorder = data.GetByteOrder();
183    size_t len;
184    switch(arch.GetCore())
185    {
186        case ArchSpec::eCore_x86_64_x86_64:
187            len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
188            return len == ELFLINUXPRPSINFO64_SIZE;
189        default:
190            return false;
191    }
192}
193
194