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