]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
MFC r258054: Update LLDB to upstream r194122 snapshot
[FreeBSD/stable/10.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_mips64.h"
21 #include "RegisterContextFreeBSD_x86_64.h"
22 #include "RegisterContextPOSIXCore_mips64.h"
23 #include "RegisterContextPOSIXCore_x86_64.h"
24
25 using namespace lldb;
26 using namespace lldb_private;
27
28 //----------------------------------------------------------------------
29 // Construct a Thread object with given data
30 //----------------------------------------------------------------------
31 ThreadElfCore::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
42 ThreadElfCore::~ThreadElfCore ()
43 {
44     DestroyThread();
45 }
46
47 void
48 ThreadElfCore::RefreshStateAfterStop()
49 {
50     GetRegisterContext()->InvalidateIfNeeded (false);
51 }
52
53 void
54 ThreadElfCore::ClearStackFrames ()
55 {
56     Unwind *unwinder = GetUnwinder ();
57     if (unwinder)
58         unwinder->Clear();
59     Thread::ClearStackFrames();
60 }
61
62 RegisterContextSP
63 ThreadElfCore::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
71 RegisterContextSP
72 ThreadElfCore::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
136 bool
137 ThreadElfCore::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 //----------------------------------------------------------------
151 ELFLinuxPrStatus::ELFLinuxPrStatus()
152 {
153     memset(this, 0, sizeof(ELFLinuxPrStatus));
154 }
155
156 bool
157 ELFLinuxPrStatus::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 //----------------------------------------------------------------
174 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
175 {
176     memset(this, 0, sizeof(ELFLinuxPrPsInfo));
177 }
178
179 bool
180 ELFLinuxPrPsInfo::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