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