10af149a8SEugene Zelenko //===-- ThreadElfCore.h -----------------------------------------*- C++ -*-===//
24f01ff8bSAshok Thirumurthi //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64f01ff8bSAshok Thirumurthi //
74f01ff8bSAshok Thirumurthi //===----------------------------------------------------------------------===//
84f01ff8bSAshok Thirumurthi 
9*cdc514e4SJonas Devlieghere #ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
10*cdc514e4SJonas Devlieghere #define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
114f01ff8bSAshok Thirumurthi 
12bc8cc867SPavel Labath #include "Plugins/Process/elf-core/RegisterUtilities.h"
13b9c1b51eSKate Stone #include "lldb/Target/Thread.h"
14666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
15fd2c8d65SPavel Labath #include "llvm/ADT/DenseMap.h"
16bc8cc867SPavel Labath #include <string>
174f01ff8bSAshok Thirumurthi 
18b9c1b51eSKate Stone struct compat_timeval {
194e6fad57SPavel Labath   alignas(8) uint64_t tv_sec;
204e6fad57SPavel Labath   alignas(8) uint64_t tv_usec;
214f01ff8bSAshok Thirumurthi };
224f01ff8bSAshok Thirumurthi 
234f01ff8bSAshok Thirumurthi // PRSTATUS structure's size differs based on architecture.
24023dd64fSDimitar Vlahovski // This is the layout in the x86-64 arch.
25023dd64fSDimitar Vlahovski // In the i386 case we parse it manually and fill it again
26023dd64fSDimitar Vlahovski // in the same structure
27b9c1b51eSKate Stone // The gp registers are also a part of this struct, but they are handled
28b9c1b51eSKate Stone // separately
294f01ff8bSAshok Thirumurthi 
30ca965885SJoerg Sonnenberger #undef si_signo
31ca965885SJoerg Sonnenberger #undef si_code
32ca965885SJoerg Sonnenberger #undef si_errno
33ca965885SJoerg Sonnenberger 
34b9c1b51eSKate Stone struct ELFLinuxPrStatus {
354f01ff8bSAshok Thirumurthi   int32_t si_signo;
364f01ff8bSAshok Thirumurthi   int32_t si_code;
374f01ff8bSAshok Thirumurthi   int32_t si_errno;
384f01ff8bSAshok Thirumurthi 
394f01ff8bSAshok Thirumurthi   int16_t pr_cursig;
404f01ff8bSAshok Thirumurthi 
414e6fad57SPavel Labath   alignas(8) uint64_t pr_sigpend;
424e6fad57SPavel Labath   alignas(8) uint64_t pr_sighold;
434f01ff8bSAshok Thirumurthi 
444f01ff8bSAshok Thirumurthi   uint32_t pr_pid;
454f01ff8bSAshok Thirumurthi   uint32_t pr_ppid;
464f01ff8bSAshok Thirumurthi   uint32_t pr_pgrp;
474f01ff8bSAshok Thirumurthi   uint32_t pr_sid;
484f01ff8bSAshok Thirumurthi 
494f01ff8bSAshok Thirumurthi   compat_timeval pr_utime;
504f01ff8bSAshok Thirumurthi   compat_timeval pr_stime;
514f01ff8bSAshok Thirumurthi   compat_timeval pr_cutime;
524f01ff8bSAshok Thirumurthi   compat_timeval pr_cstime;
534f01ff8bSAshok Thirumurthi 
54974acf1cSEd Maste   ELFLinuxPrStatus();
554f01ff8bSAshok Thirumurthi 
56cef4119cSPavel Labath   lldb_private::Status Parse(const lldb_private::DataExtractor &data,
57cef4119cSPavel Labath                              const lldb_private::ArchSpec &arch);
584f01ff8bSAshok Thirumurthi 
59023dd64fSDimitar Vlahovski   // Return the bytesize of the structure
60023dd64fSDimitar Vlahovski   // 64 bit - just sizeof
61b9c1b51eSKate Stone   // 32 bit - hardcoded because we are reusing the struct, but some of the
62b9c1b51eSKate Stone   // members are smaller -
63023dd64fSDimitar Vlahovski   // so the layout is not the same
64cef4119cSPavel Labath   static size_t GetSize(const lldb_private::ArchSpec &arch);
654f01ff8bSAshok Thirumurthi };
664f01ff8bSAshok Thirumurthi 
67b9c1b51eSKate Stone static_assert(sizeof(ELFLinuxPrStatus) == 112,
68b9c1b51eSKate Stone               "sizeof ELFLinuxPrStatus is not correct!");
694e6fad57SPavel Labath 
701a2ac9bdSHoward Hellyer struct ELFLinuxSigInfo {
711a2ac9bdSHoward Hellyer   int32_t si_signo;
721a2ac9bdSHoward Hellyer   int32_t si_code;
731a2ac9bdSHoward Hellyer   int32_t si_errno;
741a2ac9bdSHoward Hellyer 
751a2ac9bdSHoward Hellyer   ELFLinuxSigInfo();
761a2ac9bdSHoward Hellyer 
77cef4119cSPavel Labath   lldb_private::Status Parse(const lldb_private::DataExtractor &data,
781a2ac9bdSHoward Hellyer                              const lldb_private::ArchSpec &arch);
791a2ac9bdSHoward Hellyer 
801a2ac9bdSHoward Hellyer   // Return the bytesize of the structure
811a2ac9bdSHoward Hellyer   // 64 bit - just sizeof
821a2ac9bdSHoward Hellyer   // 32 bit - hardcoded because we are reusing the struct, but some of the
831a2ac9bdSHoward Hellyer   // members are smaller -
841a2ac9bdSHoward Hellyer   // so the layout is not the same
85b8dbd323SNitesh Jain   static size_t GetSize(const lldb_private::ArchSpec &arch);
861a2ac9bdSHoward Hellyer };
871a2ac9bdSHoward Hellyer 
881a2ac9bdSHoward Hellyer static_assert(sizeof(ELFLinuxSigInfo) == 12,
891a2ac9bdSHoward Hellyer               "sizeof ELFLinuxSigInfo is not correct!");
901a2ac9bdSHoward Hellyer 
91023dd64fSDimitar Vlahovski // PRPSINFO structure's size differs based on architecture.
92023dd64fSDimitar Vlahovski // This is the layout in the x86-64 arch case.
93023dd64fSDimitar Vlahovski // In the i386 case we parse it manually and fill it again
94023dd64fSDimitar Vlahovski // in the same structure
95b9c1b51eSKate Stone struct ELFLinuxPrPsInfo {
964f01ff8bSAshok Thirumurthi   char pr_state;
974f01ff8bSAshok Thirumurthi   char pr_sname;
984f01ff8bSAshok Thirumurthi   char pr_zomb;
994f01ff8bSAshok Thirumurthi   char pr_nice;
1004e6fad57SPavel Labath   alignas(8) uint64_t pr_flag;
1014f01ff8bSAshok Thirumurthi   uint32_t pr_uid;
1024f01ff8bSAshok Thirumurthi   uint32_t pr_gid;
1034f01ff8bSAshok Thirumurthi   int32_t pr_pid;
1044f01ff8bSAshok Thirumurthi   int32_t pr_ppid;
1054f01ff8bSAshok Thirumurthi   int32_t pr_pgrp;
1064f01ff8bSAshok Thirumurthi   int32_t pr_sid;
1074f01ff8bSAshok Thirumurthi   char pr_fname[16];
1084f01ff8bSAshok Thirumurthi   char pr_psargs[80];
1094f01ff8bSAshok Thirumurthi 
110974acf1cSEd Maste   ELFLinuxPrPsInfo();
1114f01ff8bSAshok Thirumurthi 
112cef4119cSPavel Labath   lldb_private::Status Parse(const lldb_private::DataExtractor &data,
113cef4119cSPavel Labath                              const lldb_private::ArchSpec &arch);
1144f01ff8bSAshok Thirumurthi 
115023dd64fSDimitar Vlahovski   // Return the bytesize of the structure
116023dd64fSDimitar Vlahovski   // 64 bit - just sizeof
117b9c1b51eSKate Stone   // 32 bit - hardcoded because we are reusing the struct, but some of the
118b9c1b51eSKate Stone   // members are smaller -
119023dd64fSDimitar Vlahovski   // so the layout is not the same
120cef4119cSPavel Labath   static size_t GetSize(const lldb_private::ArchSpec &arch);
1214f01ff8bSAshok Thirumurthi };
1224f01ff8bSAshok Thirumurthi 
123b9c1b51eSKate Stone static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
124b9c1b51eSKate Stone               "sizeof ELFLinuxPrPsInfo is not correct!");
1254e6fad57SPavel Labath 
126b9c1b51eSKate Stone struct ThreadData {
127c05ae522SEd Maste   lldb_private::DataExtractor gpregset;
128bc8cc867SPavel Labath   std::vector<lldb_private::CoreNote> notes;
129343ad623SEd Maste   lldb::tid_t tid;
1301a2ac9bdSHoward Hellyer   int signo = 0;
1311a2ac9bdSHoward Hellyer   int prstatus_sig = 0;
132c05ae522SEd Maste   std::string name;
133c05ae522SEd Maste };
134c05ae522SEd Maste 
135b9c1b51eSKate Stone class ThreadElfCore : public lldb_private::Thread {
1364f01ff8bSAshok Thirumurthi public:
137343ad623SEd Maste   ThreadElfCore(lldb_private::Process &process, const ThreadData &td);
1384f01ff8bSAshok Thirumurthi 
1390af149a8SEugene Zelenko   ~ThreadElfCore() override;
1404f01ff8bSAshok Thirumurthi 
141b9c1b51eSKate Stone   void RefreshStateAfterStop() override;
1424f01ff8bSAshok Thirumurthi 
143b9c1b51eSKate Stone   lldb::RegisterContextSP GetRegisterContext() override;
1444f01ff8bSAshok Thirumurthi 
1450af149a8SEugene Zelenko   lldb::RegisterContextSP
1460af149a8SEugene Zelenko   CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
1474f01ff8bSAshok Thirumurthi 
ThreadIDIsValid(lldb::tid_t thread)148b9c1b51eSKate Stone   static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
1494f01ff8bSAshok Thirumurthi 
GetName()150b9c1b51eSKate Stone   const char *GetName() override {
1514f01ff8bSAshok Thirumurthi     if (m_thread_name.empty())
152248a1305SKonrad Kleine       return nullptr;
1534f01ff8bSAshok Thirumurthi     return m_thread_name.c_str();
1544f01ff8bSAshok Thirumurthi   }
1554f01ff8bSAshok Thirumurthi 
SetName(const char * name)156b9c1b51eSKate Stone   void SetName(const char *name) override {
1574f01ff8bSAshok Thirumurthi     if (name && name[0])
1584f01ff8bSAshok Thirumurthi       m_thread_name.assign(name);
1594f01ff8bSAshok Thirumurthi     else
1604f01ff8bSAshok Thirumurthi       m_thread_name.clear();
1614f01ff8bSAshok Thirumurthi   }
1624f01ff8bSAshok Thirumurthi 
1634f01ff8bSAshok Thirumurthi protected:
1644f01ff8bSAshok Thirumurthi   // Member variables.
1654f01ff8bSAshok Thirumurthi   std::string m_thread_name;
1664f01ff8bSAshok Thirumurthi   lldb::RegisterContextSP m_thread_reg_ctx_sp;
1674f01ff8bSAshok Thirumurthi 
168c05ae522SEd Maste   int m_signo;
169c05ae522SEd Maste 
170c05ae522SEd Maste   lldb_private::DataExtractor m_gpregset_data;
171bc8cc867SPavel Labath   std::vector<lldb_private::CoreNote> m_notes;
1724f01ff8bSAshok Thirumurthi 
1730af149a8SEugene Zelenko   bool CalculateStopInfo() override;
1744f01ff8bSAshok Thirumurthi };
1754f01ff8bSAshok Thirumurthi 
176*cdc514e4SJonas Devlieghere #endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
177