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