]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
Update LLDB snapshot to upstream r241361
[FreeBSD/FreeBSD.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/Core/Log.h"
12 #include "lldb/Target/RegisterContext.h"
13 #include "lldb/Target/StopInfo.h"
14 #include "lldb/Target/Target.h"
15 #include "lldb/Target/Unwind.h"
16
17 #include "ThreadElfCore.h"
18 #include "ProcessElfCore.h"
19 #include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
20 #include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
21 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
22 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
23 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h"
24 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
25 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
26 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
27 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
28 #include "RegisterContextPOSIXCore_arm.h"
29 #include "RegisterContextPOSIXCore_arm64.h"
30 #include "RegisterContextPOSIXCore_mips64.h"
31 #include "RegisterContextPOSIXCore_powerpc.h"
32 #include "RegisterContextPOSIXCore_x86_64.h"
33
34 using namespace lldb;
35 using namespace lldb_private;
36
37 //----------------------------------------------------------------------
38 // Construct a Thread object with given data
39 //----------------------------------------------------------------------
40 ThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
41                               const ThreadData &td) :
42     Thread(process, tid),
43     m_thread_name(td.name),
44     m_thread_reg_ctx_sp (),
45     m_signo(td.signo),
46     m_gpregset_data(td.gpregset),
47     m_fpregset_data(td.fpregset),
48     m_vregset_data(td.vregset)
49 {
50 }
51
52 ThreadElfCore::~ThreadElfCore ()
53 {
54     DestroyThread();
55 }
56
57 void
58 ThreadElfCore::RefreshStateAfterStop()
59 {
60     GetRegisterContext()->InvalidateIfNeeded (false);
61 }
62
63 void
64 ThreadElfCore::ClearStackFrames ()
65 {
66     Unwind *unwinder = GetUnwinder ();
67     if (unwinder)
68         unwinder->Clear();
69     Thread::ClearStackFrames();
70 }
71
72 RegisterContextSP
73 ThreadElfCore::GetRegisterContext ()
74 {
75     if (m_reg_context_sp.get() == NULL) {
76         m_reg_context_sp = CreateRegisterContextForFrame (NULL);
77     }
78     return m_reg_context_sp;
79 }
80
81 RegisterContextSP
82 ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
83 {
84     RegisterContextSP reg_ctx_sp;
85     uint32_t concrete_frame_idx = 0;
86     Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
87
88     if (frame)
89         concrete_frame_idx = frame->GetConcreteFrameIndex ();
90
91     if (concrete_frame_idx == 0)
92     {
93         if (m_thread_reg_ctx_sp)
94             return m_thread_reg_ctx_sp;
95
96         ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
97         ArchSpec arch = process->GetArchitecture();
98         RegisterInfoInterface *reg_interface = NULL;
99
100         switch (arch.GetTriple().getOS())
101         {
102             case llvm::Triple::FreeBSD:
103             {
104                 switch (arch.GetMachine())
105                 {
106                     case llvm::Triple::aarch64:
107                         reg_interface = new RegisterContextFreeBSD_arm64(arch);
108                         break;
109                     case llvm::Triple::arm:
110                         reg_interface = new RegisterContextFreeBSD_arm(arch);
111                         break;
112                     case llvm::Triple::ppc:
113                         reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
114                         break;
115                     case llvm::Triple::ppc64:
116                         reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
117                         break;
118                     case llvm::Triple::mips64:
119                         reg_interface = new RegisterContextFreeBSD_mips64(arch);
120                         break;
121                     case llvm::Triple::x86:
122                         reg_interface = new RegisterContextFreeBSD_i386(arch);
123                         break;
124                     case llvm::Triple::x86_64:
125                         reg_interface = new RegisterContextFreeBSD_x86_64(arch);
126                         break;
127                     default:
128                         break;
129                 }
130                 break;
131             }
132
133             case llvm::Triple::Linux:
134             {
135                 switch (arch.GetMachine())
136                 {
137                     case llvm::Triple::arm:
138                         reg_interface = new RegisterContextLinux_arm(arch);
139                         break;
140                     case llvm::Triple::aarch64:
141                         reg_interface = new RegisterContextLinux_arm64(arch);
142                         break;
143                     case llvm::Triple::x86_64:
144                         reg_interface = new RegisterContextLinux_x86_64(arch);
145                         break;
146                     default:
147                         break;
148                 }
149                 break;
150             }
151
152             default:
153                 break;
154         }
155
156         if (!reg_interface) {
157             if (log)
158                 log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
159                              __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
160                 assert (false && "Architecture or OS not supported");
161         }
162
163         switch (arch.GetMachine())
164         {
165             case llvm::Triple::aarch64:
166                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
167                 break;
168             case llvm::Triple::arm:
169                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm (*this, reg_interface, m_gpregset_data, m_fpregset_data));
170                 break;
171             case llvm::Triple::mips64:
172                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
173                 break;
174             case llvm::Triple::ppc:
175             case llvm::Triple::ppc64:
176                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
177                 break;
178             case llvm::Triple::x86:
179             case llvm::Triple::x86_64:
180                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
181                 break;
182             default:
183                 break;
184         }
185
186         reg_ctx_sp = m_thread_reg_ctx_sp;
187     }
188     else if (m_unwinder_ap.get())
189     {
190         reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
191     }
192     return reg_ctx_sp;
193 }
194
195 bool
196 ThreadElfCore::CalculateStopInfo ()
197 {
198     ProcessSP process_sp (GetProcess());
199     if (process_sp)
200     {
201         SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
202         return true;
203     }
204     return false;
205 }
206
207 //----------------------------------------------------------------
208 // Parse PRSTATUS from NOTE entry
209 //----------------------------------------------------------------
210 ELFLinuxPrStatus::ELFLinuxPrStatus()
211 {
212     memset(this, 0, sizeof(ELFLinuxPrStatus));
213 }
214
215 bool
216 ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
217 {
218     ByteOrder byteorder = data.GetByteOrder();
219     size_t len;
220     switch(arch.GetCore())
221     {
222         case ArchSpec::eCore_x86_64_x86_64:
223             len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
224             return len == ELFLINUXPRSTATUS64_SIZE;
225         default:
226             return false;
227     }
228 }
229
230 //----------------------------------------------------------------
231 // Parse PRPSINFO from NOTE entry
232 //----------------------------------------------------------------
233 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
234 {
235     memset(this, 0, sizeof(ELFLinuxPrPsInfo));
236 }
237
238 bool
239 ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
240 {
241     ByteOrder byteorder = data.GetByteOrder();
242     size_t len;
243     switch(arch.GetCore())
244     {
245         case ArchSpec::eCore_x86_64_x86_64:
246             len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
247             return len == ELFLINUXPRPSINFO64_SIZE;
248         default:
249             return false;
250     }
251 }
252