1 //===-- ThreadElfCore.cpp -------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Target/RegisterContext.h" 10 #include "lldb/Target/StopInfo.h" 11 #include "lldb/Target/Target.h" 12 #include "lldb/Target/Unwind.h" 13 #include "lldb/Utility/DataExtractor.h" 14 #include "lldb/Utility/LLDBLog.h" 15 #include "lldb/Utility/Log.h" 16 #include "lldb/Utility/ProcessInfo.h" 17 18 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" 19 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" 20 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" 21 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" 22 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" 23 #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" 24 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 25 #include "Plugins/Process/Utility/RegisterContextNetBSD_i386.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 "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h" 32 #include "ProcessElfCore.h" 33 #include "RegisterContextLinuxCore_x86_64.h" 34 #include "RegisterContextPOSIXCore_arm.h" 35 #include "RegisterContextPOSIXCore_arm64.h" 36 #include "RegisterContextPOSIXCore_mips64.h" 37 #include "RegisterContextPOSIXCore_powerpc.h" 38 #include "RegisterContextPOSIXCore_ppc64le.h" 39 #include "RegisterContextPOSIXCore_riscv64.h" 40 #include "RegisterContextPOSIXCore_s390x.h" 41 #include "RegisterContextPOSIXCore_x86_64.h" 42 #include "ThreadElfCore.h" 43 44 #include <memory> 45 46 using namespace lldb; 47 using namespace lldb_private; 48 49 // Construct a Thread object with given data 50 ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td) 51 : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(), 52 m_signo(td.signo), m_code(td.code), m_gpregset_data(td.gpregset), 53 m_notes(td.notes) {} 54 55 ThreadElfCore::~ThreadElfCore() { DestroyThread(); } 56 57 void ThreadElfCore::RefreshStateAfterStop() { 58 GetRegisterContext()->InvalidateIfNeeded(false); 59 } 60 61 RegisterContextSP ThreadElfCore::GetRegisterContext() { 62 if (!m_reg_context_sp) { 63 m_reg_context_sp = CreateRegisterContextForFrame(nullptr); 64 } 65 return m_reg_context_sp; 66 } 67 68 RegisterContextSP 69 ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { 70 RegisterContextSP reg_ctx_sp; 71 uint32_t concrete_frame_idx = 0; 72 Log *log = GetLog(LLDBLog::Thread); 73 74 if (frame) 75 concrete_frame_idx = frame->GetConcreteFrameIndex(); 76 77 bool is_linux = false; 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 = nullptr; 85 86 switch (arch.GetTriple().getOS()) { 87 case llvm::Triple::FreeBSD: { 88 switch (arch.GetMachine()) { 89 case llvm::Triple::aarch64: 90 case llvm::Triple::arm: 91 break; 92 case llvm::Triple::ppc: 93 reg_interface = new RegisterContextFreeBSD_powerpc32(arch); 94 break; 95 case llvm::Triple::ppc64: 96 reg_interface = new RegisterContextFreeBSD_powerpc64(arch); 97 break; 98 case llvm::Triple::mips64: 99 reg_interface = new RegisterContextFreeBSD_mips64(arch); 100 break; 101 case llvm::Triple::x86: 102 reg_interface = new RegisterContextFreeBSD_i386(arch); 103 break; 104 case llvm::Triple::x86_64: 105 reg_interface = new RegisterContextFreeBSD_x86_64(arch); 106 break; 107 default: 108 break; 109 } 110 break; 111 } 112 113 case llvm::Triple::NetBSD: { 114 switch (arch.GetMachine()) { 115 case llvm::Triple::aarch64: 116 break; 117 case llvm::Triple::x86: 118 reg_interface = new RegisterContextNetBSD_i386(arch); 119 break; 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 is_linux = true; 131 switch (arch.GetMachine()) { 132 case llvm::Triple::aarch64: 133 break; 134 case llvm::Triple::ppc64le: 135 reg_interface = new RegisterInfoPOSIX_ppc64le(arch); 136 break; 137 case llvm::Triple::systemz: 138 reg_interface = new RegisterContextLinux_s390x(arch); 139 break; 140 case llvm::Triple::x86: 141 reg_interface = new RegisterContextLinux_i386(arch); 142 break; 143 case llvm::Triple::x86_64: 144 reg_interface = new RegisterContextLinux_x86_64(arch); 145 break; 146 default: 147 break; 148 } 149 break; 150 } 151 152 case llvm::Triple::OpenBSD: { 153 switch (arch.GetMachine()) { 154 case llvm::Triple::aarch64: 155 break; 156 case llvm::Triple::x86: 157 reg_interface = new RegisterContextOpenBSD_i386(arch); 158 break; 159 case llvm::Triple::x86_64: 160 reg_interface = new RegisterContextOpenBSD_x86_64(arch); 161 break; 162 default: 163 break; 164 } 165 break; 166 } 167 168 default: 169 break; 170 } 171 172 if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64 && 173 arch.GetMachine() != llvm::Triple::arm && 174 arch.GetMachine() != llvm::Triple::riscv64) { 175 LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported", 176 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); 177 assert(false && "Architecture or OS not supported"); 178 } 179 180 switch (arch.GetMachine()) { 181 case llvm::Triple::aarch64: 182 m_thread_reg_ctx_sp = RegisterContextCorePOSIX_arm64::Create( 183 *this, arch, m_gpregset_data, m_notes); 184 break; 185 case llvm::Triple::arm: 186 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>( 187 *this, std::make_unique<RegisterInfoPOSIX_arm>(arch), m_gpregset_data, 188 m_notes); 189 break; 190 case llvm::Triple::riscv64: 191 m_thread_reg_ctx_sp = RegisterContextCorePOSIX_riscv64::Create( 192 *this, arch, m_gpregset_data, m_notes); 193 break; 194 case llvm::Triple::mipsel: 195 case llvm::Triple::mips: 196 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>( 197 *this, reg_interface, m_gpregset_data, m_notes); 198 break; 199 case llvm::Triple::mips64: 200 case llvm::Triple::mips64el: 201 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>( 202 *this, reg_interface, m_gpregset_data, m_notes); 203 break; 204 case llvm::Triple::ppc: 205 case llvm::Triple::ppc64: 206 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_powerpc>( 207 *this, reg_interface, m_gpregset_data, m_notes); 208 break; 209 case llvm::Triple::ppc64le: 210 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_ppc64le>( 211 *this, reg_interface, m_gpregset_data, m_notes); 212 break; 213 case llvm::Triple::systemz: 214 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_s390x>( 215 *this, reg_interface, m_gpregset_data, m_notes); 216 break; 217 case llvm::Triple::x86: 218 case llvm::Triple::x86_64: 219 if (is_linux) { 220 m_thread_reg_ctx_sp = std::make_shared<RegisterContextLinuxCore_x86_64>( 221 *this, reg_interface, m_gpregset_data, m_notes); 222 } else { 223 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>( 224 *this, reg_interface, m_gpregset_data, m_notes); 225 } 226 break; 227 default: 228 break; 229 } 230 231 reg_ctx_sp = m_thread_reg_ctx_sp; 232 } else { 233 reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); 234 } 235 return reg_ctx_sp; 236 } 237 238 bool ThreadElfCore::CalculateStopInfo() { 239 ProcessSP process_sp(GetProcess()); 240 if (!process_sp) 241 return false; 242 243 SetStopInfo(StopInfo::CreateStopReasonWithSignal( 244 *this, m_signo, /*description=*/nullptr, m_code)); 245 return true; 246 } 247 248 // Parse PRSTATUS from NOTE entry 249 ELFLinuxPrStatus::ELFLinuxPrStatus() { 250 memset(this, 0, sizeof(ELFLinuxPrStatus)); 251 } 252 253 size_t ELFLinuxPrStatus::GetSize(const lldb_private::ArchSpec &arch) { 254 constexpr size_t mips_linux_pr_status_size_o32 = 96; 255 constexpr size_t mips_linux_pr_status_size_n32 = 72; 256 constexpr size_t num_ptr_size_members = 10; 257 if (arch.IsMIPS()) { 258 std::string abi = arch.GetTargetABI(); 259 assert(!abi.empty() && "ABI is not set"); 260 if (!abi.compare("n64")) 261 return sizeof(ELFLinuxPrStatus); 262 else if (!abi.compare("o32")) 263 return mips_linux_pr_status_size_o32; 264 // N32 ABI 265 return mips_linux_pr_status_size_n32; 266 } 267 switch (arch.GetCore()) { 268 case lldb_private::ArchSpec::eCore_x86_32_i386: 269 case lldb_private::ArchSpec::eCore_x86_32_i486: 270 return 72; 271 default: 272 if (arch.GetAddressByteSize() == 8) 273 return sizeof(ELFLinuxPrStatus); 274 else 275 return sizeof(ELFLinuxPrStatus) - num_ptr_size_members * 4; 276 } 277 } 278 279 Status ELFLinuxPrStatus::Parse(const DataExtractor &data, 280 const ArchSpec &arch) { 281 Status error; 282 if (GetSize(arch) > data.GetByteSize()) { 283 error = Status::FromErrorStringWithFormat( 284 "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64, 285 GetSize(arch), data.GetByteSize()); 286 return error; 287 } 288 289 // Read field by field to correctly account for endianess of both the core 290 // dump and the platform running lldb. 291 offset_t offset = 0; 292 si_signo = data.GetU32(&offset); 293 si_code = data.GetU32(&offset); 294 si_errno = data.GetU32(&offset); 295 296 pr_cursig = data.GetU16(&offset); 297 offset += 2; // pad 298 299 pr_sigpend = data.GetAddress(&offset); 300 pr_sighold = data.GetAddress(&offset); 301 302 pr_pid = data.GetU32(&offset); 303 pr_ppid = data.GetU32(&offset); 304 pr_pgrp = data.GetU32(&offset); 305 pr_sid = data.GetU32(&offset); 306 307 pr_utime.tv_sec = data.GetAddress(&offset); 308 pr_utime.tv_usec = data.GetAddress(&offset); 309 310 pr_stime.tv_sec = data.GetAddress(&offset); 311 pr_stime.tv_usec = data.GetAddress(&offset); 312 313 pr_cutime.tv_sec = data.GetAddress(&offset); 314 pr_cutime.tv_usec = data.GetAddress(&offset); 315 316 pr_cstime.tv_sec = data.GetAddress(&offset); 317 pr_cstime.tv_usec = data.GetAddress(&offset); 318 319 return error; 320 } 321 322 static struct compat_timeval 323 copy_timespecs(const ProcessInstanceInfo::timespec &oth) { 324 using sec_t = decltype(compat_timeval::tv_sec); 325 using usec_t = decltype(compat_timeval::tv_usec); 326 return {static_cast<sec_t>(oth.tv_sec), static_cast<usec_t>(oth.tv_usec)}; 327 } 328 329 std::optional<ELFLinuxPrStatus> 330 ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { 331 ELFLinuxPrStatus prstatus{}; 332 prstatus.pr_pid = thread_sp->GetID(); 333 lldb::ProcessSP process_sp = thread_sp->GetProcess(); 334 ProcessInstanceInfo info; 335 if (!process_sp->GetProcessInfo(info)) 336 return std::nullopt; 337 338 prstatus.pr_ppid = info.GetParentProcessID(); 339 prstatus.pr_pgrp = info.GetProcessGroupID(); 340 prstatus.pr_sid = info.GetProcessSessionID(); 341 prstatus.pr_utime = copy_timespecs(info.GetUserTime()); 342 prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); 343 prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); 344 prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); 345 return prstatus; 346 } 347 348 // Parse PRPSINFO from NOTE entry 349 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { 350 memset(this, 0, sizeof(ELFLinuxPrPsInfo)); 351 } 352 353 size_t ELFLinuxPrPsInfo::GetSize(const lldb_private::ArchSpec &arch) { 354 constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128; 355 if (arch.IsMIPS()) { 356 uint8_t address_byte_size = arch.GetAddressByteSize(); 357 if (address_byte_size == 8) 358 return sizeof(ELFLinuxPrPsInfo); 359 return mips_linux_pr_psinfo_size_o32_n32; 360 } 361 362 switch (arch.GetCore()) { 363 case lldb_private::ArchSpec::eCore_s390x_generic: 364 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 365 return sizeof(ELFLinuxPrPsInfo); 366 case lldb_private::ArchSpec::eCore_x86_32_i386: 367 case lldb_private::ArchSpec::eCore_x86_32_i486: 368 return 124; 369 default: 370 return 0; 371 } 372 } 373 374 Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, 375 const ArchSpec &arch) { 376 Status error; 377 ByteOrder byteorder = data.GetByteOrder(); 378 if (GetSize(arch) > data.GetByteSize()) { 379 error = Status::FromErrorStringWithFormat( 380 "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64, 381 GetSize(arch), data.GetByteSize()); 382 return error; 383 } 384 size_t size = 0; 385 offset_t offset = 0; 386 387 pr_state = data.GetU8(&offset); 388 pr_sname = data.GetU8(&offset); 389 pr_zomb = data.GetU8(&offset); 390 pr_nice = data.GetU8(&offset); 391 if (data.GetAddressByteSize() == 8) { 392 // Word align the next field on 64 bit. 393 offset += 4; 394 } 395 396 pr_flag = data.GetAddress(&offset); 397 398 if (arch.IsMIPS()) { 399 // The pr_uid and pr_gid is always 32 bit irrespective of platforms 400 pr_uid = data.GetU32(&offset); 401 pr_gid = data.GetU32(&offset); 402 } else { 403 // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms 404 pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 405 pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1); 406 } 407 408 pr_pid = data.GetU32(&offset); 409 pr_ppid = data.GetU32(&offset); 410 pr_pgrp = data.GetU32(&offset); 411 pr_sid = data.GetU32(&offset); 412 413 size = 16; 414 data.ExtractBytes(offset, size, byteorder, pr_fname); 415 offset += size; 416 417 size = 80; 418 data.ExtractBytes(offset, size, byteorder, pr_psargs); 419 offset += size; 420 421 return error; 422 } 423 424 std::optional<ELFLinuxPrPsInfo> 425 ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { 426 ProcessInstanceInfo info; 427 if (!process_sp->GetProcessInfo(info)) 428 return std::nullopt; 429 430 return Populate(info, process_sp->GetState()); 431 } 432 433 std::optional<ELFLinuxPrPsInfo> 434 ELFLinuxPrPsInfo::Populate(const lldb_private::ProcessInstanceInfo &info, 435 lldb::StateType process_state) { 436 ELFLinuxPrPsInfo prpsinfo{}; 437 prpsinfo.pr_pid = info.GetProcessID(); 438 prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); 439 prpsinfo.pr_zomb = 0; 440 if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { 441 prpsinfo.pr_zomb = 1; 442 } 443 /** 444 * In the linux kernel this comes from: 445 * state = READ_ONCE(p->__state); 446 * i = state ? ffz(~state) + 1 : 0; 447 * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; 448 * 449 * So we replicate that here. From proc_pid_stats(5) 450 * R = Running 451 * S = Sleeping on uninterrutible wait 452 * D = Waiting on uninterruptable disk sleep 453 * T = Tracing stop 454 * Z = Zombie 455 * W = Paging 456 */ 457 switch (process_state) { 458 case lldb::StateType::eStateSuspended: 459 prpsinfo.pr_sname = 'S'; 460 prpsinfo.pr_state = 1; 461 break; 462 case lldb::StateType::eStateStopped: 463 [[fallthrough]]; 464 case lldb::StateType::eStateStepping: 465 prpsinfo.pr_sname = 'T'; 466 prpsinfo.pr_state = 3; 467 break; 468 case lldb::StateType::eStateUnloaded: 469 [[fallthrough]]; 470 case lldb::StateType::eStateRunning: 471 prpsinfo.pr_sname = 'R'; 472 prpsinfo.pr_state = 0; 473 break; 474 default: 475 break; 476 } 477 478 /** 479 * pr_flags is left as 0. The values (in linux) are specific 480 * to the kernel. We recover them from the proc filesystem 481 * but don't put them in ProcessInfo because it would really 482 * become very linux specific and the utility here seems pretty 483 * dubious 484 */ 485 486 if (info.EffectiveUserIDIsValid()) 487 prpsinfo.pr_uid = info.GetUserID(); 488 489 if (info.EffectiveGroupIDIsValid()) 490 prpsinfo.pr_gid = info.GetGroupID(); 491 492 if (info.ParentProcessIDIsValid()) 493 prpsinfo.pr_ppid = info.GetParentProcessID(); 494 495 if (info.ProcessGroupIDIsValid()) 496 prpsinfo.pr_pgrp = info.GetProcessGroupID(); 497 498 if (info.ProcessSessionIDIsValid()) 499 prpsinfo.pr_sid = info.GetProcessSessionID(); 500 501 constexpr size_t fname_len = std::extent_v<decltype(prpsinfo.pr_fname)>; 502 static_assert(fname_len > 0, "This should always be non zero"); 503 const llvm::StringRef fname = info.GetNameAsStringRef(); 504 auto fname_begin = fname.begin(); 505 std::copy_n(fname_begin, std::min(fname_len, fname.size()), 506 prpsinfo.pr_fname); 507 prpsinfo.pr_fname[fname_len - 1] = '\0'; 508 auto args = info.GetArguments(); 509 auto argentry_iterator = std::begin(args); 510 char *psargs = prpsinfo.pr_psargs; 511 char *psargs_end = std::end(prpsinfo.pr_psargs); 512 while (psargs < psargs_end && argentry_iterator != args.end()) { 513 llvm::StringRef argentry = argentry_iterator->ref(); 514 size_t len = 515 std::min<size_t>(std::distance(psargs, psargs_end), argentry.size()); 516 auto arg_iterator = std::begin(argentry); 517 psargs = std::copy_n(arg_iterator, len, psargs); 518 if (psargs != psargs_end) 519 *(psargs++) = ' '; 520 ++argentry_iterator; 521 } 522 *(psargs - 1) = '\0'; 523 return prpsinfo; 524 } 525 526 // Parse SIGINFO from NOTE entry 527 ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); } 528 529 size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) { 530 if (arch.IsMIPS()) 531 return sizeof(ELFLinuxSigInfo); 532 switch (arch.GetCore()) { 533 case lldb_private::ArchSpec::eCore_x86_64_x86_64: 534 return sizeof(ELFLinuxSigInfo); 535 case lldb_private::ArchSpec::eCore_s390x_generic: 536 case lldb_private::ArchSpec::eCore_x86_32_i386: 537 case lldb_private::ArchSpec::eCore_x86_32_i486: 538 return 12; 539 default: 540 return 0; 541 } 542 } 543 544 Status ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) { 545 Status error; 546 if (GetSize(arch) > data.GetByteSize()) { 547 error = Status::FromErrorStringWithFormat( 548 "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64, 549 GetSize(arch), data.GetByteSize()); 550 return error; 551 } 552 553 // Parsing from a 32 bit ELF core file, and populating/reusing the structure 554 // properly, because the struct is for the 64 bit version 555 offset_t offset = 0; 556 si_signo = data.GetU32(&offset); 557 si_errno = data.GetU32(&offset); 558 si_code = data.GetU32(&offset); 559 560 return error; 561 } 562