aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process/elf-core/ThreadElfCore.h
blob: f1f00cf019b3a1e14d8b7bdee3ee1bf878cded24 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//===-- ThreadElfCore.h ----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ThreadElfCore_h_
#define liblldb_ThreadElfCore_h_

#include <string>

#include "lldb/Target/Thread.h"
#include "lldb/Core/DataExtractor.h"

struct compat_timeval
{
    int64_t tv_sec;
    int32_t tv_usec;
};

// PRSTATUS structure's size differs based on architecture.
// Currently parsing done only for x86-64 architecture by
// simply reading data from the buffer.
// The following macros are used to specify the size.
// Calculating size using sizeof() wont work because of padding.
#define ELFLINUXPRSTATUS64_SIZE (112)
#define ELFLINUXPRPSINFO64_SIZE (132)

#undef si_signo
#undef si_code
#undef si_errno

struct ELFLinuxPrStatus
{
    int32_t         si_signo;
    int32_t         si_code;
    int32_t         si_errno;

    int16_t         pr_cursig;

    uint64_t        pr_sigpend;
    uint64_t        pr_sighold;

    uint32_t        pr_pid;
    uint32_t        pr_ppid;
    uint32_t        pr_pgrp;
    uint32_t        pr_sid;

    compat_timeval  pr_utime;
    compat_timeval  pr_stime;
    compat_timeval  pr_cutime;
    compat_timeval  pr_cstime;

    ELFLinuxPrStatus();

    bool
    Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);

    static size_t
    GetSize(lldb_private::ArchSpec &arch)
    {
        switch(arch.GetCore())
        {
            case lldb_private::ArchSpec::eCore_x86_64_x86_64:
                return ELFLINUXPRSTATUS64_SIZE;
            default:
                return 0;
        }
    }
};

struct ELFLinuxPrPsInfo
{
    char        pr_state;
    char        pr_sname;
    char        pr_zomb;
    char        pr_nice;
    uint64_t    pr_flag;
    uint32_t    pr_uid;
    uint32_t    pr_gid;
    int32_t     pr_pid;
    int32_t     pr_ppid;
    int32_t     pr_pgrp;
    int32_t     pr_sid;
    char        pr_fname[16];
    char        pr_psargs[80];

    ELFLinuxPrPsInfo();

    bool
    Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);

    static size_t
    GetSize(lldb_private::ArchSpec &arch)
    {
        switch(arch.GetCore())
        {
            case lldb_private::ArchSpec::eCore_x86_64_x86_64:
                return ELFLINUXPRPSINFO64_SIZE;
            default:
                return 0;
        }
    }

};

struct ThreadData
{
    lldb_private::DataExtractor gpregset;
    lldb_private::DataExtractor fpregset;
    int signo;
    std::string name;
};

class ThreadElfCore : public lldb_private::Thread
{
public:
    ThreadElfCore (lldb_private::Process &process, lldb::tid_t tid,
                   const ThreadData &td);

    virtual
    ~ThreadElfCore ();

    virtual void
    RefreshStateAfterStop();

    virtual lldb::RegisterContextSP
    GetRegisterContext ();

    virtual lldb::RegisterContextSP
    CreateRegisterContextForFrame (lldb_private::StackFrame *frame);

    virtual void
    ClearStackFrames ();

    static bool
    ThreadIDIsValid (lldb::tid_t thread)
    {
        return thread != 0;
    }

    virtual const char *
    GetName ()
    {
        if (m_thread_name.empty())
            return NULL;
        return m_thread_name.c_str();
    }

    void
    SetName (const char *name)
    {
        if (name && name[0])
            m_thread_name.assign (name);
        else
            m_thread_name.clear();
    }

protected:
    //------------------------------------------------------------------
    // Member variables.
    //------------------------------------------------------------------
    std::string m_thread_name;
    lldb::RegisterContextSP m_thread_reg_ctx_sp;

    int m_signo;

    lldb_private::DataExtractor m_gpregset_data;
    lldb_private::DataExtractor m_fpregset_data;

    virtual bool CalculateStopInfo();

};

#endif  // liblldb_ThreadElfCore_h_