1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 #include "createdump.h"
6 #include <asm/ptrace.h>
8 #if defined(__aarch64__)
9 // See src/pal/src/include/pal/context.h
10 #define MCREG_Fp(mc) ((mc).regs[29])
11 #define MCREG_Lr(mc) ((mc).regs[30])
12 #define MCREG_Sp(mc) ((mc).sp)
13 #define MCREG_Pc(mc) ((mc).pc)
14 #define MCREG_Cpsr(mc) ((mc).pstate)
22 typedef int __ptrace_request;
25 #define FPREG_ErrorOffset(fpregs) *(DWORD*)&((fpregs).rip)
26 #define FPREG_ErrorSelector(fpregs) *(((WORD*)&((fpregs).rip)) + 2)
27 #define FPREG_DataOffset(fpregs) *(DWORD*)&((fpregs).rdp)
28 #define FPREG_DataSelector(fpregs) *(((WORD*)&((fpregs).rdp)) + 2)
30 extern CrashInfo* g_crashInfo;
32 ThreadInfo::ThreadInfo(pid_t tid) :
37 ThreadInfo::~ThreadInfo()
42 ThreadInfo::Initialize(ICLRDataTarget* pDataTarget)
44 if (!CrashInfo::GetStatus(m_tid, &m_ppid, &m_tgid, nullptr))
48 if (pDataTarget != nullptr)
50 if (!GetRegistersWithDataTarget(pDataTarget))
56 if (!GetRegistersWithPTrace())
62 #if defined(__aarch64__)
63 TRACE("Thread %04x PC %016llx SP %016llx\n", m_tid, (unsigned long long)MCREG_Pc(m_gpRegisters), (unsigned long long)MCREG_Sp(m_gpRegisters));
64 #elif defined(__arm__)
65 TRACE("Thread %04x PC %08lx SP %08lx\n", m_tid, (unsigned long)m_gpRegisters.ARM_pc, (unsigned long)m_gpRegisters.ARM_sp);
66 #elif defined(__x86_64__)
67 TRACE("Thread %04x RIP %016llx RSP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.rip, (unsigned long long)m_gpRegisters.rsp);
68 #elif defined(__i386__)
69 TRACE("Thread %04x EIP %016lx ESP %016lx\n", m_tid, (unsigned long)m_gpRegisters.eip, (unsigned long)m_gpRegisters.esp);
71 #error "Unsupported architecture"
77 ThreadInfo::ResumeThread()
79 if (ptrace(PTRACE_DETACH, m_tid, nullptr, nullptr) != -1)
82 waitpid(m_tid, &waitStatus, __WALL);
86 // Helper for UnwindNativeFrames
88 GetFrameLocation(CONTEXT* pContext, uint64_t* ip, uint64_t* sp)
90 #if defined(__x86_64__)
93 #elif defined(__i386__)
96 #elif defined(__aarch64__)
99 #elif defined(__arm__)
100 *ip = pContext->Pc & ~THUMB_CODE;
105 // Helper for UnwindNativeFrames
107 ReadMemoryAdapter(PVOID address, PVOID buffer, SIZE_T size)
109 return g_crashInfo->ReadMemory(address, buffer, size);
113 ThreadInfo::UnwindNativeFrames(CrashInfo& crashInfo, CONTEXT* pContext)
115 uint64_t previousSp = 0;
117 // For each native frame
120 uint64_t ip = 0, sp = 0;
121 GetFrameLocation(pContext, &ip, &sp);
123 TRACE("Unwind: sp %" PRIA PRIx64 " ip %" PRIA PRIx64 "\n", sp, ip);
124 if (ip == 0 || sp <= previousSp) {
128 // Add two pages around the instruction pointer to the core dump
129 crashInfo.InsertMemoryRegion(ip - PAGE_SIZE, PAGE_SIZE * 2);
131 // Look up the ip address to get the module base address
132 uint64_t baseAddress = crashInfo.GetBaseAddress(ip);
133 if (baseAddress == 0) {
134 TRACE("Unwind: module base not found ip %" PRIA PRIx64 "\n", ip);
138 // Unwind the native frame adding all the memory accessed to the
139 // core dump via the read memory adapter.
140 if (!PAL_VirtualUnwindOutOfProc(pContext, nullptr, baseAddress, ReadMemoryAdapter)) {
141 TRACE("Unwind: PAL_VirtualUnwindOutOfProc returned false\n");
149 ThreadInfo::UnwindThread(CrashInfo& crashInfo, IXCLRDataProcess* pClrDataProcess)
151 TRACE("Unwind: thread %04x\n", Tid());
153 // Get starting native context for the thread
155 GetThreadContext(CONTEXT_ALL, &context);
157 // Unwind the native frames at the top of the stack
158 UnwindNativeFrames(crashInfo, &context);
160 if (pClrDataProcess != nullptr)
162 ReleaseHolder<IXCLRDataTask> pTask;
163 ReleaseHolder<IXCLRDataStackWalk> pStackwalk;
165 // Get the managed stack walker for this thread
166 if (SUCCEEDED(pClrDataProcess->GetTaskByOSThreadID(Tid(), &pTask)))
168 pTask->CreateStackWalk(
169 CLRDATA_SIMPFRAME_UNRECOGNIZED |
170 CLRDATA_SIMPFRAME_MANAGED_METHOD |
171 CLRDATA_SIMPFRAME_RUNTIME_MANAGED_CODE |
172 CLRDATA_SIMPFRAME_RUNTIME_UNMANAGED_CODE,
176 // For each managed frame (if any)
177 if (pStackwalk != nullptr)
179 TRACE("Unwind: managed frames\n");
182 // Get the managed stack frame context
183 if (pStackwalk->GetContext(CONTEXT_ALL, sizeof(context), nullptr, (BYTE *)&context) != S_OK) {
184 TRACE("Unwind: stack walker GetContext FAILED\n");
188 // Unwind all the native frames after the managed frame
189 UnwindNativeFrames(crashInfo, &context);
191 } while (pStackwalk->Next() == S_OK);
199 ThreadInfo::GetRegistersWithPTrace()
201 #if defined(__aarch64__)
202 struct iovec gpRegsVec = { &m_gpRegisters, sizeof(m_gpRegisters) };
203 if (ptrace((__ptrace_request)PTRACE_GETREGSET, m_tid, NT_PRSTATUS, &gpRegsVec) == -1)
205 fprintf(stderr, "ptrace(PTRACE_GETREGSET, %d, NT_PRSTATUS) FAILED %d (%s)\n", m_tid, errno, strerror(errno));
208 assert(sizeof(m_gpRegisters) == gpRegsVec.iov_len);
210 struct iovec fpRegsVec = { &m_fpRegisters, sizeof(m_fpRegisters) };
211 if (ptrace((__ptrace_request)PTRACE_GETREGSET, m_tid, NT_FPREGSET, &fpRegsVec) == -1)
213 fprintf(stderr, "ptrace(PTRACE_GETREGSET, %d, NT_FPREGSET) FAILED %d (%s)\n", m_tid, errno, strerror(errno));
216 assert(sizeof(m_fpRegisters) == fpRegsVec.iov_len);
218 if (ptrace((__ptrace_request)PTRACE_GETREGS, m_tid, nullptr, &m_gpRegisters) == -1)
220 fprintf(stderr, "ptrace(GETREGS, %d) FAILED %d (%s)\n", m_tid, errno, strerror(errno));
223 if (ptrace((__ptrace_request)PTRACE_GETFPREGS, m_tid, nullptr, &m_fpRegisters) == -1)
225 fprintf(stderr, "ptrace(GETFPREGS, %d) FAILED %d (%s)\n", m_tid, errno, strerror(errno));
228 #if defined(__i386__)
229 if (ptrace((__ptrace_request)PTRACE_GETFPXREGS, m_tid, nullptr, &m_fpxRegisters) == -1)
231 fprintf(stderr, "ptrace(GETFPXREGS, %d) FAILED %d (%s)\n", m_tid, errno, strerror(errno));
234 #elif defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__)
236 #if defined(ARM_VFPREGS_SIZE)
237 assert(sizeof(m_vfpRegisters) == ARM_VFPREGS_SIZE);
240 if (ptrace((__ptrace_request)PTRACE_GETVFPREGS, m_tid, nullptr, &m_vfpRegisters) == -1)
242 fprintf(stderr, "ptrace(PTRACE_GETVFPREGS, %d) FAILED %d (%s)\n", m_tid, errno, strerror(errno));
249 void ThreadInfo::SetRegisters(elf_prstatus *prstatus)
251 #if defined(__x86_64__)
252 struct user_regs_struct *u_reg = (struct user_regs_struct *)&prstatus->pr_reg;
253 m_gpRegisters.rip = u_reg->rip;
254 m_gpRegisters.rbp = u_reg->rbp;
255 m_gpRegisters.rsp = u_reg->rsp;
257 m_gpRegisters.rax = u_reg->rax;
258 m_gpRegisters.rbx = u_reg->rbx;
259 m_gpRegisters.rcx = u_reg->rcx;
260 m_gpRegisters.rdx = u_reg->rdx;
261 m_gpRegisters.rsi = u_reg->rsi;
262 m_gpRegisters.rdi = u_reg->rdi;
264 m_gpRegisters.cs = u_reg->cs;
265 m_gpRegisters.gs = u_reg->gs;
266 m_gpRegisters.es = u_reg->es;
267 m_gpRegisters.fs = u_reg->fs;
268 m_gpRegisters.ds = u_reg->ds;
269 m_gpRegisters.ss = u_reg->ss;
270 m_gpRegisters.fs_base = u_reg->fs_base;
271 m_gpRegisters.gs_base = u_reg->gs_base;
273 m_gpRegisters.orig_rax = u_reg->orig_rax;
275 m_gpRegisters.r8 = u_reg->r8;
276 m_gpRegisters.r9 = u_reg->r9;
277 m_gpRegisters.r10 = u_reg->r10;
278 m_gpRegisters.r11 = u_reg->r11;
279 m_gpRegisters.r12 = u_reg->r12;
280 m_gpRegisters.r13 = u_reg->r13;
281 m_gpRegisters.r14 = u_reg->r14;
282 m_gpRegisters.r15 = u_reg->r15;
284 m_gpRegisters.eflags = u_reg->eflags;
285 #elif defined(__i386__)
286 struct user_regs_struct *u_reg = (struct user_regs_struct *)&prstatus->pr_reg;
287 m_gpRegisters.ebx = u_reg->ebx;
288 m_gpRegisters.ecx = u_reg->ecx;
289 m_gpRegisters.edx = u_reg->edx;
290 m_gpRegisters.esi = u_reg->esi;
291 m_gpRegisters.edi = u_reg->edi;
292 m_gpRegisters.ebp = u_reg->ebp;
293 m_gpRegisters.eax = u_reg->eax;
294 m_gpRegisters.xds = u_reg->xds;
295 m_gpRegisters.xes = u_reg->xes;
296 m_gpRegisters.xfs = u_reg->xfs;
297 m_gpRegisters.xgs = u_reg->xgs;
298 m_gpRegisters.orig_eax = u_reg->orig_eax;
299 m_gpRegisters.eip = u_reg->eip;
300 m_gpRegisters.xcs = u_reg->xcs;
301 m_gpRegisters.eflags = u_reg->eflags;
302 m_gpRegisters.esp = u_reg->esp;
303 m_gpRegisters.xss = u_reg->xss;
304 #elif defined(__arm__)
306 #define REGS_REGULAR_NUM 13
313 struct user_regs *u_reg = (struct user_regs *)&prstatus->pr_reg;
314 m_gpRegisters.ARM_sp = u_reg->uregs[REG_SP];
315 m_gpRegisters.ARM_lr = u_reg->uregs[REG_LR];
316 m_gpRegisters.ARM_pc = u_reg->uregs[REG_PC];
317 m_gpRegisters.ARM_cpsr = u_reg->uregs[REG_SPSR];
319 m_gpRegisters.ARM_r0 = u_reg->uregs[0];
320 m_gpRegisters.ARM_ORIG_r0 = u_reg->uregs[0];
321 m_gpRegisters.ARM_r1 = u_reg->uregs[1];
322 m_gpRegisters.ARM_r2 = u_reg->uregs[2];
323 m_gpRegisters.ARM_r3 = u_reg->uregs[3];
324 m_gpRegisters.ARM_r4 = u_reg->uregs[4];
325 m_gpRegisters.ARM_r5 = u_reg->uregs[5];
326 m_gpRegisters.ARM_r6 = u_reg->uregs[6];
327 m_gpRegisters.ARM_r7 = u_reg->uregs[7];
328 m_gpRegisters.ARM_r8 = u_reg->uregs[8];
329 m_gpRegisters.ARM_r9 = u_reg->uregs[9];
330 m_gpRegisters.ARM_r10 = u_reg->uregs[10];
331 m_gpRegisters.ARM_fp = u_reg->uregs[REG_FP];
332 m_gpRegisters.ARM_ip = u_reg->uregs[REG_IP];
337 ThreadInfo::GetRegistersWithDataTarget(ICLRDataTarget* pDataTarget)
340 context.ContextFlags = CONTEXT_ALL;
341 if (pDataTarget->GetThreadContext(m_tid, context.ContextFlags, sizeof(context), reinterpret_cast<PBYTE>(&context)) != S_OK)
345 #if defined(__x86_64__)
346 m_gpRegisters.rbp = context.Rbp;
347 m_gpRegisters.rip = context.Rip;
348 m_gpRegisters.cs = context.SegCs;
349 m_gpRegisters.eflags = context.EFlags;
350 m_gpRegisters.ss = context.SegSs;
351 m_gpRegisters.rsp = context.Rsp;
352 m_gpRegisters.rdi = context.Rdi;
354 m_gpRegisters.rsi = context.Rsi;
355 m_gpRegisters.rbx = context.Rbx;
356 m_gpRegisters.rdx = context.Rdx;
357 m_gpRegisters.rcx = context.Rcx;
358 m_gpRegisters.rax = context.Rax;
359 m_gpRegisters.orig_rax = context.Rax;
360 m_gpRegisters.r8 = context.R8;
361 m_gpRegisters.r9 = context.R9;
362 m_gpRegisters.r10 = context.R10;
363 m_gpRegisters.r11 = context.R11;
364 m_gpRegisters.r12 = context.R12;
365 m_gpRegisters.r13 = context.R13;
366 m_gpRegisters.r14 = context.R14;
367 m_gpRegisters.r15 = context.R15;
369 m_gpRegisters.ds = context.SegDs;
370 m_gpRegisters.es = context.SegEs;
371 m_gpRegisters.fs = context.SegFs;
372 m_gpRegisters.gs = context.SegGs;
373 m_gpRegisters.fs_base = 0;
374 m_gpRegisters.gs_base = 0;
376 m_fpRegisters.cwd = context.FltSave.ControlWord;
377 m_fpRegisters.swd = context.FltSave.StatusWord;
378 m_fpRegisters.ftw = context.FltSave.TagWord;
379 m_fpRegisters.fop = context.FltSave.ErrorOpcode;
381 FPREG_ErrorOffset(m_fpRegisters) = context.FltSave.ErrorOffset;
382 FPREG_ErrorSelector(m_fpRegisters) = context.FltSave.ErrorSelector;
383 FPREG_DataOffset(m_fpRegisters) = context.FltSave.DataOffset;
384 FPREG_DataSelector(m_fpRegisters) = context.FltSave.DataSelector;
386 m_fpRegisters.mxcsr = context.FltSave.MxCsr;
387 m_fpRegisters.mxcr_mask = context.FltSave.MxCsr_Mask;
389 assert(sizeof(context.FltSave.FloatRegisters) == sizeof(m_fpRegisters.st_space));
390 memcpy(m_fpRegisters.st_space, context.FltSave.FloatRegisters, sizeof(m_fpRegisters.st_space));
392 assert(sizeof(context.FltSave.XmmRegisters) == sizeof(m_fpRegisters.xmm_space));
393 memcpy(m_fpRegisters.xmm_space, context.FltSave.XmmRegisters, sizeof(m_fpRegisters.xmm_space));
394 #elif defined(__aarch64__)
395 // See MCREG maps in PAL's context.h
396 assert(sizeof(m_gpRegisters.regs) == (sizeof(context.X) + sizeof(context.Fp) + sizeof(context.Lr)));
397 memcpy(m_gpRegisters.regs, context.X, sizeof(context.X));
398 MCREG_Fp(m_gpRegisters) = context.Fp;
399 MCREG_Lr(m_gpRegisters) = context.Lr;
400 MCREG_Sp(m_gpRegisters) = context.Sp;
401 MCREG_Pc(m_gpRegisters) = context.Pc;
402 MCREG_Cpsr(m_gpRegisters) = context.Cpsr;
404 assert(sizeof(m_fpRegisters.vregs) == sizeof(context.V));
405 memcpy(m_fpRegisters.vregs, context.V, sizeof(context.V));
406 m_fpRegisters.fpcr = context.Fpcr;
407 m_fpRegisters.fpsr = context.Fpsr;
408 #elif defined(__arm__)
409 m_gpRegisters.ARM_sp = context.Sp;
410 m_gpRegisters.ARM_lr = context.Lr;
411 m_gpRegisters.ARM_pc = context.Pc;
412 m_gpRegisters.ARM_cpsr = context.Cpsr;
414 m_gpRegisters.ARM_r0 = context.R0;
415 m_gpRegisters.ARM_ORIG_r0 = context.R0;
416 m_gpRegisters.ARM_r1 = context.R1;
417 m_gpRegisters.ARM_r2 = context.R2;
418 m_gpRegisters.ARM_r3 = context.R3;
419 m_gpRegisters.ARM_r4 = context.R4;
420 m_gpRegisters.ARM_r5 = context.R5;
421 m_gpRegisters.ARM_r6 = context.R6;
422 m_gpRegisters.ARM_r7 = context.R7;
423 m_gpRegisters.ARM_r8 = context.R8;
424 m_gpRegisters.ARM_r9 = context.R9;
425 m_gpRegisters.ARM_r10 = context.R10;
426 m_gpRegisters.ARM_fp = context.R11;
427 m_gpRegisters.ARM_ip = context.R12;
429 #if defined(__VFP_FP__) && !defined(__SOFTFP__)
430 m_vfpRegisters.fpscr = context.Fpscr;
432 assert(sizeof(context.D) == sizeof(m_vfpRegisters.fpregs));
433 memcpy(m_vfpRegisters.fpregs, context.D, sizeof(context.D));
435 #elif defined(__i386__)
436 m_gpRegisters.ebp = context.Ebp;
437 m_gpRegisters.eip = context.Eip;
438 m_gpRegisters.eflags = context.EFlags;
439 m_gpRegisters.esp = context.Esp;
440 m_gpRegisters.edi = context.Edi;
442 m_gpRegisters.esi = context.Esi;
443 m_gpRegisters.ebx = context.Ebx;
444 m_gpRegisters.edx = context.Edx;
445 m_gpRegisters.ecx = context.Ecx;
446 m_gpRegisters.eax = context.Eax;
447 m_gpRegisters.orig_eax = context.Eax;
449 #error Platform not supported
455 ThreadInfo::GetThreadStack(CrashInfo& crashInfo)
457 uint64_t startAddress;
460 #if defined(__aarch64__)
461 startAddress = MCREG_Sp(m_gpRegisters) & PAGE_MASK;
462 #elif defined(__arm__)
463 startAddress = m_gpRegisters.ARM_sp & PAGE_MASK;
464 #elif defined(__x86_64__)
465 startAddress = m_gpRegisters.rsp & PAGE_MASK;
466 #elif defined(__i386__)
467 startAddress = m_gpRegisters.esp & PAGE_MASK;
469 size = 4 * PAGE_SIZE;
471 MemoryRegion search(0, startAddress, startAddress + PAGE_SIZE);
472 const MemoryRegion* region = CrashInfo::SearchMemoryRegions(crashInfo.OtherMappings(), search);
473 if (region != nullptr) {
475 // Use the mapping found for the size of the thread's stack
476 size = region->EndAddress() - startAddress;
480 TRACE("Thread %04x stack found in other mapping (size %08zx): ", m_tid, size);
484 crashInfo.InsertMemoryRegion(startAddress, size);
488 ThreadInfo::GetThreadContext(uint32_t flags, CONTEXT* context) const
490 context->ContextFlags = flags;
491 #if defined(__x86_64__)
492 if ((flags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
494 context->Rbp = m_gpRegisters.rbp;
495 context->Rip = m_gpRegisters.rip;
496 context->SegCs = m_gpRegisters.cs;
497 context->EFlags = m_gpRegisters.eflags;
498 context->SegSs = m_gpRegisters.ss;
499 context->Rsp = m_gpRegisters.rsp;
501 if ((flags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
503 context->Rdi = m_gpRegisters.rdi;
504 context->Rsi = m_gpRegisters.rsi;
505 context->Rbx = m_gpRegisters.rbx;
506 context->Rdx = m_gpRegisters.rdx;
507 context->Rcx = m_gpRegisters.rcx;
508 context->Rax = m_gpRegisters.rax;
509 context->R8 = m_gpRegisters.r8;
510 context->R9 = m_gpRegisters.r9;
511 context->R10 = m_gpRegisters.r10;
512 context->R11 = m_gpRegisters.r11;
513 context->R12 = m_gpRegisters.r12;
514 context->R13 = m_gpRegisters.r13;
515 context->R14 = m_gpRegisters.r14;
516 context->R15 = m_gpRegisters.r15;
518 if ((flags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
520 context->SegDs = m_gpRegisters.ds;
521 context->SegEs = m_gpRegisters.es;
522 context->SegFs = m_gpRegisters.fs;
523 context->SegGs = m_gpRegisters.gs;
525 if ((flags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
527 context->FltSave.ControlWord = m_fpRegisters.cwd;
528 context->FltSave.StatusWord = m_fpRegisters.swd;
529 context->FltSave.TagWord = m_fpRegisters.ftw;
530 context->FltSave.ErrorOpcode = m_fpRegisters.fop;
532 context->FltSave.ErrorOffset = FPREG_ErrorOffset(m_fpRegisters);
533 context->FltSave.ErrorSelector = FPREG_ErrorSelector(m_fpRegisters);
534 context->FltSave.DataOffset = FPREG_DataOffset(m_fpRegisters);
535 context->FltSave.DataSelector = FPREG_DataSelector(m_fpRegisters);
537 context->FltSave.MxCsr = m_fpRegisters.mxcsr;
538 context->FltSave.MxCsr_Mask = m_fpRegisters.mxcr_mask;
540 assert(sizeof(context->FltSave.FloatRegisters) == sizeof(m_fpRegisters.st_space));
541 memcpy(context->FltSave.FloatRegisters, m_fpRegisters.st_space, sizeof(context->FltSave.FloatRegisters));
543 assert(sizeof(context->FltSave.XmmRegisters) == sizeof(m_fpRegisters.xmm_space));
544 memcpy(context->FltSave.XmmRegisters, m_fpRegisters.xmm_space, sizeof(context->FltSave.XmmRegisters));
546 // TODO: debug registers?
547 #elif defined(__aarch64__)
548 if ((flags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
550 context->Fp = MCREG_Fp(m_gpRegisters);
551 context->Lr = MCREG_Lr(m_gpRegisters);
552 context->Sp = MCREG_Sp(m_gpRegisters);
553 context->Pc = MCREG_Pc(m_gpRegisters);
554 context->Cpsr = MCREG_Cpsr(m_gpRegisters);
556 if ((flags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
558 assert(sizeof(m_gpRegisters.regs) == (sizeof(context->X) + sizeof(context->Fp) + sizeof(context->Lr)));
559 memcpy(context->X, m_gpRegisters.regs, sizeof(context->X));
561 if ((flags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
563 assert(sizeof(m_fpRegisters.vregs) == sizeof(context->V));
564 memcpy(context->V, m_fpRegisters.vregs, sizeof(context->V));
565 context->Fpcr = m_fpRegisters.fpcr;
566 context->Fpsr = m_fpRegisters.fpsr;
568 #elif defined(__arm__)
569 if ((flags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
571 context->Sp = m_gpRegisters.ARM_sp;
572 context->Lr = m_gpRegisters.ARM_lr;
573 context->Pc = m_gpRegisters.ARM_pc;
574 context->Cpsr = m_gpRegisters.ARM_cpsr;
576 if ((flags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
578 context->R0 = m_gpRegisters.ARM_r0;
579 context->R1 = m_gpRegisters.ARM_r1;
580 context->R2 = m_gpRegisters.ARM_r2;
581 context->R3 = m_gpRegisters.ARM_r3;
582 context->R4 = m_gpRegisters.ARM_r4;
583 context->R5 = m_gpRegisters.ARM_r5;
584 context->R6 = m_gpRegisters.ARM_r6;
585 context->R7 = m_gpRegisters.ARM_r7;
586 context->R8 = m_gpRegisters.ARM_r8;
587 context->R9 = m_gpRegisters.ARM_r9;
588 context->R10 = m_gpRegisters.ARM_r10;
589 context->R11 = m_gpRegisters.ARM_fp;
590 context->R12 = m_gpRegisters.ARM_ip;
592 if ((flags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
594 #if defined(__VFP_FP__) && !defined(__SOFTFP__)
595 context->Fpscr = m_vfpRegisters.fpscr;
597 assert(sizeof(context->D) == sizeof(m_vfpRegisters.fpregs));
598 memcpy(context->D, m_vfpRegisters.fpregs, sizeof(context->D));
601 #elif defined(__i386__)
602 if ((flags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
604 context->Ebp = m_gpRegisters.ebp;
605 context->Eip = m_gpRegisters.eip;
606 context->EFlags = m_gpRegisters.eflags;
607 context->Esp = m_gpRegisters.esp;
608 context->SegCs = m_gpRegisters.xcs;
609 context->SegSs = m_gpRegisters.xss;
610 context->SegGs_PAL_Undefined = m_gpRegisters.xgs;
611 context->SegFs_PAL_Undefined = m_gpRegisters.xfs;
612 context->SegEs_PAL_Undefined = m_gpRegisters.xes;
613 context->SegDs_PAL_Undefined = m_gpRegisters.xds;
615 if ((flags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
617 context->Edi = m_gpRegisters.edi;
618 context->Esi = m_gpRegisters.esi;
619 context->Ebx = m_gpRegisters.ebx;
620 context->Edx = m_gpRegisters.edx;
621 context->Ecx = m_gpRegisters.ecx;
622 context->Eax = m_gpRegisters.eax;
625 #error Platform not supported