]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Plugins / Process / elf-core / ThreadElfCore.cpp
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
26 using namespace lldb;
27 using namespace lldb_private;
28
29 //----------------------------------------------------------------------
30 // Construct a Thread object with given data
31 //----------------------------------------------------------------------
32 ThreadElfCore::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
43 ThreadElfCore::~ThreadElfCore ()
44 {
45     DestroyThread();
46 }
47
48 void
49 ThreadElfCore::RefreshStateAfterStop()
50 {
51     GetRegisterContext()->InvalidateIfNeeded (false);
52 }
53
54 void
55 ThreadElfCore::ClearStackFrames ()
56 {
57     Unwind *unwinder = GetUnwinder ();
58     if (unwinder)
59         unwinder->Clear();
60     Thread::ClearStackFrames();
61 }
62
63 RegisterContextSP
64 ThreadElfCore::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
72 RegisterContextSP
73 ThreadElfCore::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
158 bool
159 ThreadElfCore::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 //----------------------------------------------------------------
173 ELFLinuxPrStatus::ELFLinuxPrStatus()
174 {
175     memset(this, 0, sizeof(ELFLinuxPrStatus));
176 }
177
178 bool
179 ELFLinuxPrStatus::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 //----------------------------------------------------------------
196 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
197 {
198     memset(this, 0, sizeof(ELFLinuxPrPsInfo));
199 }
200
201 bool
202 ELFLinuxPrPsInfo::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