1254721Semaste//===-- ThreadElfCore.cpp --------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Core/DataExtractor.h"
11254721Semaste#include "lldb/Target/RegisterContext.h"
12254721Semaste#include "lldb/Target/StopInfo.h"
13254721Semaste#include "lldb/Target/Target.h"
14254721Semaste#include "lldb/Target/Unwind.h"
15254721Semaste#include "ProcessPOSIXLog.h"
16254721Semaste
17254721Semaste#include "ThreadElfCore.h"
18254721Semaste#include "ProcessElfCore.h"
19263363Semaste#include "RegisterContextLinux_x86_64.h"
20269024Semaste#include "RegisterContextFreeBSD_i386.h"
21263363Semaste#include "RegisterContextFreeBSD_mips64.h"
22263363Semaste#include "RegisterContextFreeBSD_x86_64.h"
23263363Semaste#include "RegisterContextPOSIXCore_mips64.h"
24263363Semaste#include "RegisterContextPOSIXCore_x86_64.h"
25254721Semaste
26254721Semasteusing namespace lldb;
27254721Semasteusing namespace lldb_private;
28254721Semaste
29254721Semaste//----------------------------------------------------------------------
30254721Semaste// Construct a Thread object with given data
31254721Semaste//----------------------------------------------------------------------
32254721SemasteThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
33254721Semaste                              const ThreadData &td) :
34254721Semaste    Thread(process, tid),
35254721Semaste    m_thread_name(td.name),
36254721Semaste    m_thread_reg_ctx_sp (),
37254721Semaste    m_signo(td.signo),
38254721Semaste    m_gpregset_data(td.gpregset),
39254721Semaste    m_fpregset_data(td.fpregset)
40254721Semaste{
41254721Semaste}
42254721Semaste
43254721SemasteThreadElfCore::~ThreadElfCore ()
44254721Semaste{
45254721Semaste    DestroyThread();
46254721Semaste}
47254721Semaste
48254721Semastevoid
49254721SemasteThreadElfCore::RefreshStateAfterStop()
50254721Semaste{
51254721Semaste    GetRegisterContext()->InvalidateIfNeeded (false);
52254721Semaste}
53254721Semaste
54254721Semastevoid
55254721SemasteThreadElfCore::ClearStackFrames ()
56254721Semaste{
57254721Semaste    Unwind *unwinder = GetUnwinder ();
58254721Semaste    if (unwinder)
59254721Semaste        unwinder->Clear();
60254721Semaste    Thread::ClearStackFrames();
61254721Semaste}
62254721Semaste
63254721SemasteRegisterContextSP
64254721SemasteThreadElfCore::GetRegisterContext ()
65254721Semaste{
66254721Semaste    if (m_reg_context_sp.get() == NULL) {
67254721Semaste        m_reg_context_sp = CreateRegisterContextForFrame (NULL);
68254721Semaste    }
69254721Semaste    return m_reg_context_sp;
70254721Semaste}
71254721Semaste
72254721SemasteRegisterContextSP
73254721SemasteThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
74254721Semaste{
75254721Semaste    RegisterContextSP reg_ctx_sp;
76254721Semaste    uint32_t concrete_frame_idx = 0;
77254721Semaste    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
78254721Semaste
79254721Semaste    if (frame)
80254721Semaste        concrete_frame_idx = frame->GetConcreteFrameIndex ();
81254721Semaste
82254721Semaste    if (concrete_frame_idx == 0)
83254721Semaste    {
84254721Semaste        if (m_thread_reg_ctx_sp)
85254721Semaste            return m_thread_reg_ctx_sp;
86254721Semaste
87254721Semaste        ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
88254721Semaste        ArchSpec arch = process->GetArchitecture();
89269024Semaste        RegisterInfoInterface *reg_interface = NULL;
90269024Semaste
91269024Semaste        switch (arch.GetTriple().getOS())
92254721Semaste        {
93269024Semaste            case llvm::Triple::FreeBSD:
94269024Semaste            {
95269024Semaste                switch (arch.GetMachine())
96263363Semaste                {
97269024Semaste                    case llvm::Triple::mips64:
98269024Semaste                        reg_interface = new RegisterContextFreeBSD_mips64(arch);
99263363Semaste                        break;
100269024Semaste                    case llvm::Triple::x86:
101269024Semaste                        reg_interface = new RegisterContextFreeBSD_i386(arch);
102269024Semaste                        break;
103269024Semaste                    case llvm::Triple::x86_64:
104269024Semaste                        reg_interface = new RegisterContextFreeBSD_x86_64(arch);
105269024Semaste                        break;
106263363Semaste                    default:
107263363Semaste                        break;
108263363Semaste                }
109263363Semaste                break;
110269024Semaste            }
111269024Semaste
112269024Semaste            case llvm::Triple::Linux:
113269024Semaste            {
114269024Semaste                switch (arch.GetMachine())
115254721Semaste                {
116269024Semaste                    case llvm::Triple::x86_64:
117269024Semaste                        reg_interface = new RegisterContextLinux_x86_64(arch);
118254721Semaste                        break;
119254721Semaste                    default:
120254721Semaste                        break;
121254721Semaste                }
122254721Semaste                break;
123269024Semaste            }
124269024Semaste
125254721Semaste            default:
126269024Semaste                break;
127254721Semaste        }
128269024Semaste
129269024Semaste        if (!reg_interface) {
130269024Semaste            if (log)
131269024Semaste                log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
132269024Semaste                             __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
133269024Semaste                assert (false && "Architecture or OS not supported");
134269024Semaste        }
135269024Semaste
136269024Semaste        switch (arch.GetMachine())
137269024Semaste        {
138269024Semaste            case llvm::Triple::mips64:
139269024Semaste                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
140269024Semaste                break;
141269024Semaste            case llvm::Triple::x86:
142269024Semaste            case llvm::Triple::x86_64:
143269024Semaste                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
144269024Semaste                break;
145269024Semaste            default:
146269024Semaste                break;
147269024Semaste        }
148269024Semaste
149254721Semaste        reg_ctx_sp = m_thread_reg_ctx_sp;
150254721Semaste    }
151254721Semaste    else if (m_unwinder_ap.get())
152254721Semaste    {
153254721Semaste        reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
154254721Semaste    }
155254721Semaste    return reg_ctx_sp;
156254721Semaste}
157254721Semaste
158254721Semastebool
159254721SemasteThreadElfCore::CalculateStopInfo ()
160254721Semaste{
161254721Semaste    ProcessSP process_sp (GetProcess());
162254721Semaste    if (process_sp)
163254721Semaste    {
164254721Semaste        SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
165254721Semaste        return true;
166254721Semaste    }
167254721Semaste    return false;
168254721Semaste}
169254721Semaste
170254721Semaste//----------------------------------------------------------------
171254721Semaste// Parse PRSTATUS from NOTE entry
172254721Semaste//----------------------------------------------------------------
173254721SemasteELFLinuxPrStatus::ELFLinuxPrStatus()
174254721Semaste{
175254721Semaste    memset(this, 0, sizeof(ELFLinuxPrStatus));
176254721Semaste}
177254721Semaste
178254721Semastebool
179254721SemasteELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
180254721Semaste{
181254721Semaste    ByteOrder byteorder = data.GetByteOrder();
182254721Semaste    size_t len;
183254721Semaste    switch(arch.GetCore())
184254721Semaste    {
185254721Semaste        case ArchSpec::eCore_x86_64_x86_64:
186254721Semaste            len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
187254721Semaste            return len == ELFLINUXPRSTATUS64_SIZE;
188254721Semaste        default:
189254721Semaste            return false;
190254721Semaste    }
191254721Semaste}
192254721Semaste
193254721Semaste//----------------------------------------------------------------
194254721Semaste// Parse PRPSINFO from NOTE entry
195254721Semaste//----------------------------------------------------------------
196254721SemasteELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
197254721Semaste{
198254721Semaste    memset(this, 0, sizeof(ELFLinuxPrPsInfo));
199254721Semaste}
200254721Semaste
201254721Semastebool
202254721SemasteELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
203254721Semaste{
204254721Semaste    ByteOrder byteorder = data.GetByteOrder();
205254721Semaste    size_t len;
206254721Semaste    switch(arch.GetCore())
207254721Semaste    {
208254721Semaste        case ArchSpec::eCore_x86_64_x86_64:
209254721Semaste            len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
210254721Semaste            return len == ELFLINUXPRPSINFO64_SIZE;
211254721Semaste        default:
212254721Semaste            return false;
213254721Semaste    }
214254721Semaste}
215254721Semaste
216