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