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