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