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