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