]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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 "RegisterContextCoreFreeBSD_x86_64.h"
20 #include "RegisterContextCoreLinux_x86_64.h"
21
22 using namespace lldb;
23 using namespace lldb_private;
24
25 //----------------------------------------------------------------------
26 // Construct a Thread object with given data
27 //----------------------------------------------------------------------
28 ThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
29                               const ThreadData &td) :
30     Thread(process, tid),
31     m_thread_name(td.name),
32     m_thread_reg_ctx_sp (),
33     m_signo(td.signo),
34     m_gpregset_data(td.gpregset),
35     m_fpregset_data(td.fpregset)
36 {
37 }
38
39 ThreadElfCore::~ThreadElfCore ()
40 {
41     DestroyThread();
42 }
43
44 void
45 ThreadElfCore::RefreshStateAfterStop()
46 {
47     GetRegisterContext()->InvalidateIfNeeded (false);
48 }
49
50 void
51 ThreadElfCore::ClearStackFrames ()
52 {
53     Unwind *unwinder = GetUnwinder ();
54     if (unwinder)
55         unwinder->Clear();
56     Thread::ClearStackFrames();
57 }
58
59 RegisterContextSP
60 ThreadElfCore::GetRegisterContext ()
61 {
62     if (m_reg_context_sp.get() == NULL) {
63         m_reg_context_sp = CreateRegisterContextForFrame (NULL);
64     }
65     return m_reg_context_sp;
66 }
67
68 RegisterContextSP
69 ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
70 {
71     RegisterContextSP reg_ctx_sp;
72     uint32_t concrete_frame_idx = 0;
73     Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
74
75     if (frame)
76         concrete_frame_idx = frame->GetConcreteFrameIndex ();
77
78     if (concrete_frame_idx == 0)
79     {
80         if (m_thread_reg_ctx_sp)
81             return m_thread_reg_ctx_sp;
82
83         ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
84         ArchSpec arch = process->GetArchitecture();
85         switch (arch.GetMachine())
86         {
87             case llvm::Triple::x86_64:
88                 switch (arch.GetTriple().getOS())
89                 {
90                     case llvm::Triple::FreeBSD:
91                         m_thread_reg_ctx_sp.reset(new RegisterContextCoreFreeBSD_x86_64 (*this, m_gpregset_data, m_fpregset_data));
92                         break;
93                     case llvm::Triple::Linux:
94                         m_thread_reg_ctx_sp.reset(new RegisterContextCoreLinux_x86_64 (*this, 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             default:
105                 if (log)
106                     log->Printf ("elf-core::%s:: Architecture(%d) not supported",
107                                  __FUNCTION__, arch.GetMachine());
108                 assert (false && "Architecture not supported");
109         }
110         reg_ctx_sp = m_thread_reg_ctx_sp;
111     }
112     else if (m_unwinder_ap.get())
113     {
114         reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
115     }
116     return reg_ctx_sp;
117 }
118
119 bool
120 ThreadElfCore::CalculateStopInfo ()
121 {
122     ProcessSP process_sp (GetProcess());
123     if (process_sp)
124     {
125         SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
126         return true;
127     }
128     return false;
129 }
130
131 //----------------------------------------------------------------
132 // Parse PRSTATUS from NOTE entry
133 //----------------------------------------------------------------
134 ELFLinuxPrStatus::ELFLinuxPrStatus()
135 {
136     memset(this, 0, sizeof(ELFLinuxPrStatus));
137 }
138
139 bool
140 ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
141 {
142     ByteOrder byteorder = data.GetByteOrder();
143     size_t len;
144     switch(arch.GetCore())
145     {
146         case ArchSpec::eCore_x86_64_x86_64:
147             len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
148             return len == ELFLINUXPRSTATUS64_SIZE;
149         default:
150             return false;
151     }
152 }
153
154 //----------------------------------------------------------------
155 // Parse PRPSINFO from NOTE entry
156 //----------------------------------------------------------------
157 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
158 {
159     memset(this, 0, sizeof(ELFLinuxPrPsInfo));
160 }
161
162 bool
163 ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
164 {
165     ByteOrder byteorder = data.GetByteOrder();
166     size_t len;
167     switch(arch.GetCore())
168     {
169         case ArchSpec::eCore_x86_64_x86_64:
170             len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
171             return len == ELFLINUXPRPSINFO64_SIZE;
172         default:
173             return false;
174     }
175 }
176