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/Target/RegisterContext.h" 11 #include "lldb/Target/StopInfo.h" 12 #include "lldb/Target/Target.h" 13 #include "lldb/Target/Unwind.h" 14 #include "lldb/Utility/DataExtractor.h" 15 #include "lldb/Utility/Log.h" 16 17 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" 18 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" 19 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" 20 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" 21 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" 22 #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" 23 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 24 #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" 25 #include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h" 26 #include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h" 27 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" 28 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" 29 #include "ProcessElfCore.h" 30 #include "RegisterContextPOSIXCore_arm.h" 31 #include "RegisterContextPOSIXCore_arm64.h" 32 #include "RegisterContextPOSIXCore_mips64.h" 33 #include "RegisterContextPOSIXCore_powerpc.h" 34 #include "RegisterContextPOSIXCore_s390x.h" 35 #include "RegisterContextPOSIXCore_x86_64.h" 36 #include "ThreadElfCore.h" 37 38 using namespace lldb; 39 using namespace lldb_private; 40 41 //---------------------------------------------------------------------- 42 // Construct a Thread object with given data 43 //---------------------------------------------------------------------- 44 ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td) 45 : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(), 46 m_signo(td.signo), m_gpregset_data(td.gpregset), 47 m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {} 48 49 ThreadElfCore::~ThreadElfCore() { DestroyThread(); } 50 51 void ThreadElfCore::RefreshStateAfterStop() { 52 GetRegisterContext()->InvalidateIfNeeded(false); 53 } 54 55 void ThreadElfCore::ClearStackFrames() { 56 Unwind *unwinder = GetUnwinder(); 57 if (unwinder) 58 unwinder->Clear(); 59 Thread::ClearStackFrames(); 60 } 61 62 RegisterContextSP ThreadElfCore::GetRegisterContext() { 63 if (m_reg_context_sp.get() == NULL) { 64 m_reg_context_sp = CreateRegisterContextForFrame(NULL); 65 } 66 return m_reg_context_sp; 67 } 68 69 RegisterContextSP 70 ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { 71 RegisterContextSP reg_ctx_sp; 72 uint32_t concrete_frame_idx = 0; 73 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); 74 75 if (frame) 76 concrete_frame_idx = frame->GetConcreteFrameIndex(); 77 78 if (concrete_frame_idx == 0) { 79 if (m_thread_reg_ctx_sp) 80 return m_thread_reg_ctx_sp; 81 82 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get()); 83 ArchSpec arch = process->GetArchitecture(); 84 RegisterInfoInterface *reg_interface = NULL; 85 86 switch (arch.GetTriple().getOS()) { 87 case llvm::Triple::FreeBSD: { 88 switch (arch.GetMachine()) { 89 case llvm::Triple::aarch64: 90 reg_interface = new RegisterInfoPOSIX_arm64(arch); 91 break; 92 case llvm::Triple::arm: 93 reg_interface = new RegisterInfoPOSIX_arm(arch); 94 break; 95 case llvm::Triple::ppc: 96 reg_interface = new RegisterContextFreeBSD_powerpc32(arch); 97 break; 98 case llvm::Triple::ppc64: 99 reg_interface = new RegisterContextFreeBSD_powerpc64(arch); 100 break; 101 case llvm::Triple::mips64: 102 reg_interface = new RegisterContextFreeBSD_mips64(arch); 103 break; 104 case llvm::Triple::x86: 105 reg_interface = new RegisterContextFreeBSD_i386(arch); 106 break; 107 case llvm::Triple::x86_64: 108 reg_interface = new RegisterContextFreeBSD_x86_64(arch); 109 break; 110 default: 111 break; 112 } 113 break; 114 } 115 116 case llvm::Triple::NetBSD: { 117 switch (arch.GetMachine()) { 118 case llvm::Triple::x86_64: 119 reg_interface = new RegisterContextNetBSD_x86_64(arch); 120 break; 121 default: 122 break; 123 } 124 break; 125 } 126 127 case llvm::Triple::Linux: { 128 switch (arch.GetMachine()) { 129 case llvm::Triple::arm: 130 reg_interface = new RegisterInfoPOSIX_arm(arch); 131 break; 132 case llvm::Triple::aarch64: 133 reg_interface = new RegisterInfoPOSIX_arm64(arch); 134 break; 135 case llvm::Triple::systemz: 136 reg_interface = new RegisterContextLinux_s390x(arch); 137 break; 138 case llvm::Triple::x86: 139 reg_interface = new RegisterContextLinux_i386(arch); 140 break; 141 case llvm::Triple::x86_64: 142 reg_interface = new RegisterContextLinux_x86_64(arch); 143 break; 144 default: 145 break; 146 } 147 break; 148 } 149 150 case llvm::Triple::OpenBSD: { 151 switch (arch.GetMachine()) { 152 case llvm::Triple::aarch64: 153 reg_interface = new RegisterInfoPOSIX_arm64(arch); 154 break; 155 case llvm::Triple::arm: 156 reg_interface = new RegisterInfoPOSIX_arm(arch); 157 break; 158 case llvm::Triple::x86: 159 reg_interface = new RegisterContextOpenBSD_i386(arch); 160 break; 161 case llvm::Triple::x86_64: 162 reg_interface = new RegisterContextOpenBSD_x86_64(arch); 163 break; 164 default: 165 break; 166 } 167 break; 168 } 169 170 default: 171 break; 172 } 173 174 if (!reg_interface) { 175 if (log) 176 log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported", 177 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); 178 assert(false && "Architecture or OS not supported"); 179 } 180 181 switch (arch.GetMachine()) { 182 case llvm::Triple::aarch64: 183 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64( 184 *this, reg_interface, m_gpregset_data, m_fpregset_data)); 185 break; 186 case llvm::Triple::arm: 187 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm( 188 *this, reg_interface, m_gpregset_data, m_fpregset_data)); 189 break; 190 case llvm::Triple::mips64: 191 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64( 192 *this, reg_interface, m_gpregset_data, m_fpregset_data)); 193 break; 194 case llvm::Triple::ppc: 195 case llvm::Triple::ppc64: 196 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc( 197 *this, reg_interface, m_gpregset_data, m_fpregset_data, 198 m_vregset_data)); 199 break; 200 case llvm::Triple::systemz: 201 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x( 202 *this, reg_interface, m_gpregset_data, m_fpregset_data)); 203 break; 204 case llvm::Triple::x86: 205 case llvm::Triple::x86_64: 206 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64( 207 *this, reg_interface, m_gpregset_data, m_fpregset_data)); 208 break; 209 default: 210 break; 211 } 212 213 reg_ctx_sp = m_thread_reg_ctx_sp; 214 } else if (m_unwinder_ap.get()) { 215 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame); 216 } 217 return reg_ctx_sp; 218 } 219 220 bool ThreadElfCore::CalculateStopInfo() { 221 ProcessSP process_sp(GetProcess()); 222 if (process_sp) { 223 SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo)); 224 return true; 225 } 226 return false; 227 } 228 229 //---------------------------------------------------------------- 230 // Parse PRSTATUS from NOTE entry 231 //---------------------------------------------------------------- 232 ELFLinuxPrStatus::ELFLinuxPrStatus() { 233 memset(this, 0, sizeof(ELFLinuxPrStatus)); 234 } 235 236 Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) { 237 Error error; 238 if (GetSize(arch) > data.GetByteSize()) { 239 error.SetErrorStringWithFormat( 240 "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64, 241 GetSize(arch), data.GetByteSize()); 242 return error; 243 } 244 245 // Read field by field to correctly account for endianess 246 // of both the core dump and the platform running lldb. 247 offset_t offset = 0; 248 si_signo = data.GetU32(&offset); 249 si_code = data.GetU32(&offset); 250 si_errno = data.GetU32(&offset); 251 252 pr_cursig = data.GetU16(&offset); 253 offset += 2; // pad 254 255 pr_sigpend = data.GetPointer(&offset); 256 pr_sighold = data.GetPointer(&offset); 257 258 pr_pid = data.GetU32(&offset); 259 pr_ppid = data.GetU32(&offset); 260 pr_pgrp = data.GetU32(&offset); 261 pr_sid = data.GetU32(&offset); 262 263 pr_utime.tv_sec = data.GetPointer(&offset); 264 pr_utime.tv_usec = data.GetPointer(&offset); 265 266 pr_stime.tv_sec = data.GetPointer(&offset); 267 pr_stime.tv_usec = data.GetPointer(&offset); 268 269 pr_cutime.tv_sec = data.GetPointer(&offset); 270 pr_cutime.tv_usec = data.GetPointer(&offset); 271 272 pr_cstime.tv_sec = data.GetPointer(&offset); 273 pr_cstime.tv_usec = data.GetPointer(&offset); 274 275 return error; 276 } 277 278 //---------------------------------------------------------------- 279 // Parse PRPSINFO from NOTE entry 280 //---------------------------------------------------------------- 281 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { 282 memset(this, 0, sizeof(ELFLinuxPrPsInfo)); 283 } 284 285 Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) { 286 Error error; 287 ByteOrder byteorder = data.GetByteOrder(); 288 if (GetSize(arch) > data.GetByteSize()) { 289 error.SetErrorStringWithFormat( 290 "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64, 291 GetSize(arch), data.GetByteSize()); 292 return error; 293 } 294 size_t size = 0; 295 offset_t offset = 0; 296 297 pr_state = data.GetU8(&offset); 298 pr_sname = data.GetU8(&offset); 299 pr_zomb = data.GetU8(&offset); 300 pr_nice = data.GetU8(&offset); 301 if (data.GetAddressByteSize() == 8) { 302 // Word align the next field on 64 bit. 303 offset += 4; 304 } 305 306 pr_flag = data.GetPointer(&offset); 307 308 // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms 309 pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 310 pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 311 312 pr_pid = data.GetU32(&offset); 313 pr_ppid = data.GetU32(&offset); 314 pr_pgrp = data.GetU32(&offset); 315 pr_sid = data.GetU32(&offset); 316 317 size = 16; 318 data.ExtractBytes(offset, size, byteorder, pr_fname); 319 offset += size; 320 321 size = 80; 322 data.ExtractBytes(offset, size, byteorder, pr_psargs); 323 offset += size; 324 325 return error; 326 } 327 328 //---------------------------------------------------------------- 329 // Parse SIGINFO from NOTE entry 330 //---------------------------------------------------------------- 331 ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); } 332 333 Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) { 334 Error error; 335 if (GetSize(arch) > data.GetByteSize()) { 336 error.SetErrorStringWithFormat( 337 "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64, 338 GetSize(arch), data.GetByteSize()); 339 return error; 340 } 341 342 // Parsing from a 32 bit ELF core file, and populating/reusing the structure 343 // properly, because the struct is for the 64 bit version 344 offset_t offset = 0; 345 si_signo = data.GetU32(&offset); 346 si_code = data.GetU32(&offset); 347 si_errno = data.GetU32(&offset); 348 349 return error; 350 } 351