| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- ///////////////////////////////////////////////////////////////////////////////
- // Copyright (c) Electronic Arts Inc. All rights reserved.
- ///////////////////////////////////////////////////////////////////////////////
- #if defined(EA_PRAGMA_ONCE_SUPPORTED)
- #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
- #endif
- #ifndef EATHREAD_EATHREAD_CALLSTACK_CONTEXT_H
- #define EATHREAD_EATHREAD_CALLSTACK_CONTEXT_H
- #include <EABase/eabase.h>
- #include <eathread/internal/config.h>
- #include <stddef.h>
- EA_DISABLE_VC_WARNING(4201)
- namespace EA
- {
- namespace Thread
- {
- /// CallstackContext
- ///
- /// Processor-specific information that's needed to walk a call stack.
- ///
- enum CallstackContextType
- {
- CALLSTACK_CONTEXT_UNKNOWN = 0,
- CALLSTACK_CONTEXT_POWERPC,
- CALLSTACK_CONTEXT_X86,
- CALLSTACK_CONTEXT_X86_64,
- CALLSTACK_CONTEXT_ARM,
- CALLSTACK_CONTEXT_ARM64,
- CALLSTACK_CONTEXT_MIPS,
- CALLSTACK_CONTEXT_SPU,
- NUMBER_OF_CALLSTACK_CONTEXT_TYPES
- };
- // NOTE: These context structures were moved to this header as of EAThread version 1.17.02
- // TODO: We should evaluate if these really do belong here.
- // The following are base values required for processor-agnostic offline stack dumping.
- // Not all implementations will fill them in, and most times only the base and pointer
- // will be filled. Also, most of the specific contexts' will have a member with the
- // same value as the stack pointer, i.e. mESP on the x86
- struct CallstackContextBase
- {
- uintptr_t mStackBase; /// Used to help tell what the valid stack ranges is. 0 if not used.
- uintptr_t mStackLimit; /// "
- uintptr_t mStackPointer; /// "
- CallstackContextBase() : mStackBase(0), mStackLimit(0), mStackPointer(0) {}
- };
- struct CallstackContextPowerPC : public CallstackContextBase
- {
- uintptr_t mGPR1; /// General purpose register 1.
- uintptr_t mIAR; /// Instruction address pseudo-register.
-
- CallstackContextPowerPC() : mGPR1(0), mIAR(0) {}
- };
- struct CallstackContextX86 : public CallstackContextBase
- {
- uint32_t mEIP; /// Instruction pointer.
- uint32_t mESP; /// Stack pointer.
- uint32_t mEBP; /// Base pointer.
- CallstackContextX86() : mEIP(0), mESP(0), mEBP(0) {}
- };
- #if defined(EA_PROCESSOR_X86)
- struct CallstackContext : public CallstackContextX86
- {
- static const CallstackContextType kType = CALLSTACK_CONTEXT_X86;
- };
- #endif
- struct CallstackContextX86_64 : public CallstackContextBase
- {
- uint64_t mRIP; /// Instruction pointer.
- uint64_t mRSP; /// Stack pointer.
- uint64_t mRBP; /// Base pointer.
- CallstackContextX86_64() : mRIP(0), mRSP(0), mRBP(0) {}
- };
- #if defined(EA_PROCESSOR_X86_64)
- struct CallstackContext : public CallstackContextX86_64
- {
- static const CallstackContextType kType = CALLSTACK_CONTEXT_X86_64;
- };
- #endif
- struct CallstackContextARM : public CallstackContextBase
- {
- uint32_t mFP; /// Frame pointer; register 11 for ARM instructions, register 7 for Thumb instructions.
- uint32_t mSP; /// Stack pointer; register 13
- uint32_t mLR; /// Link register; register 14
- uint32_t mPC; /// Program counter; register 15
- CallstackContextARM() : mFP(0), mSP(0), mLR(0), mPC(0) {}
- };
- #if defined(EA_PROCESSOR_ARM32)
- struct CallstackContext : public CallstackContextARM
- {
- static const CallstackContextType kType = CALLSTACK_CONTEXT_ARM;
- };
- #endif
- struct CallstackContextARM64 : public CallstackContextBase
- {
- uint64_t mFP; /// Frame pointer; register 29
- uint64_t mSP; /// Stack pointer; register SP
- uint64_t mLR; /// Link register; register 30
- uint64_t mPC; /// Program counter; register PC
- CallstackContextARM64() : mFP(0), mSP(0), mLR(0), mPC(0) {}
- };
- #if defined(EA_PROCESSOR_ARM64)
- struct CallstackContext : public CallstackContextARM64
- {
- static const CallstackContextType kType = CALLSTACK_CONTEXT_ARM64;
- };
- #endif
- struct CallstackContextMIPS : public CallstackContextBase
- {
- uintptr_t mPC; /// Program counter.
- uintptr_t mSP; /// Stack pointer.
- uintptr_t mFP; /// Frame pointer.
- uintptr_t mRA; /// Return address.
- CallstackContextMIPS() : mPC(0), mSP(0), mFP(0), mRA(0) {}
- };
- struct CallstackContextSPU : public CallstackContextBase
- {
- uint32_t mGPR0; /// General purpose register 0, word 0: return address. If this is zero then we can still read a call stack, but simply lose the first entry.
- uint32_t mGPR1; /// General purpose register 1, word 0: caller stack frame address. This is required to be set in order to read the call stack properly.
- CallstackContextSPU() : mGPR0(0), mGPR1(0) {}
- };
- union VMXRegister
- {
- uint8_t mByte [16 / sizeof(uint8_t )];
- uint16_t mHalfword[16 / sizeof(uint16_t)];
- uint32_t mWord [16 / sizeof(uint32_t)];
- uint64_t mDword [16 / sizeof(uint64_t)]; // Some VMX implementations don't support 64 bit integers.
- float mFloat [16 / sizeof(float)];
- double mDouble [16 / sizeof(double)]; // Some VMX implementations don't support 64 bit doubles.
- };
- /// ContextPowerPC32
- ///
- /// This is a generic 32 bit PowerPC with VMX context.
- ///
- struct ContextPowerPC32
- {
- uint32_t mGpr[32]; // General registers 0..31
- uint32_t mCr; // Condition register
- uint32_t mXer; // Fixed point exception register
- uint32_t mLr; // Link register
- uint32_t mCtr; // Count register low
- uint32_t mCtrHigh; // Count register high
- uint32_t mIar; // Instruction address register
- uint32_t mMsr; // Machine status register
- double mFpr[32]; // Floating registers 0..31
- double mFpscr; // Floating point status/control reg
- VMXRegister mVr[32]; // Vector registers 0..127
- VMXRegister mVscr; // Vector status/control register
- }; // ContextPowerPC32
- /// ContextPowerPC64
- ///
- /// This is a generic 64 bit PowerPC with VMX context.
- ///
- struct ContextPowerPC64
- {
- uint64_t mGpr[32]; // General registers 0..31
- uint64_t mCr; // Condition register
- uint64_t mXer; // Fixed point exception register
- uint64_t mLr; // Link register
- uint64_t mCtr; // Count register
- uint64_t mIar; // Instruction address register
- uint64_t mMsr; // Machine status register
- double mFpr[32]; // Floating registers 0..31
- double mFpscr; // Floating point status/control reg
- VMXRegister mVr[32]; // Vector registers 0..127
- VMXRegister mVscr; // Vector status/control register
- }; // ContextPowerPC64
- /// ContextX86
- ///
- /// Generic Intel x86 context.
- /// This is a duplicate of the CONTEXT structure defined by Microsoft in WinNT.h.
- ///
- struct ContextX86
- {
- uint32_t ContextFlags;
- uint32_t Dr0;
- uint32_t Dr1;
- uint32_t Dr2;
- uint32_t Dr3;
- uint32_t Dr6;
- uint32_t Dr7;
- // FLOATING_SAVE_AREA
- uint32_t Controluint32_t;
- uint32_t Statusuint32_t;
- uint32_t Taguint32_t;
- uint32_t ErrorOffset;
- uint32_t ErrorSelector;
- uint32_t DataOffset;
- uint32_t DataSelector;
- uint8_t RegisterArea[80];
- uint32_t Cr0NpxState;
- uint32_t SegGs;
- uint32_t SegFs;
- uint32_t SegEs;
- uint32_t SegDs;
- uint32_t Edi;
- uint32_t Esi;
- uint32_t Ebx;
- uint32_t Edx;
- uint32_t Ecx;
- uint32_t Eax;
- uint32_t Ebp;
- uint32_t Eip;
- uint32_t SegCs;
- uint32_t EFlags;
- uint32_t Esp;
- uint32_t SegSs;
- uint8_t ExtendedRegisters[512];
- }; // ContextX86
- #ifdef EA_PROCESSOR_X86 // Win32, Linux, OSX.
- struct Context : public ContextX86
- {
- // Empty
- };
- #endif
- /// ContextX86_64
- ///
- /// Generic Intel x86-64 context.
- /// This is a duplicate of the CONTEXT structure defined
- /// by Microsoft in WinNT.h in VC8 and later.
- ///
- EA_PREFIX_ALIGN(16)
- struct M128A_
- {
- uint64_t Low;
- int64_t High;
- }EA_POSTFIX_ALIGN(16);
- struct XMM_SAVE_AREA32_
- {
- uint16_t ControlWord;
- uint16_t StatusWord;
- uint8_t TagWord;
- uint8_t Reserved1;
- uint16_t ErrorOpcode;
- uint32_t ErrorOffset;
- uint16_t ErrorSelector;
- uint16_t Reserved2;
- uint32_t DataOffset;
- uint16_t DataSelector;
- uint16_t Reserved3;
- uint32_t MxCsr;
- uint32_t MxCsr_Mask;
- M128A_ FloatRegisters[8];
- M128A_ XmmRegisters[16];
- uint8_t Reserved4[96];
- };
- EA_PREFIX_ALIGN(16) struct ContextX86_64
- {
- uint64_t P1Home;
- uint64_t P2Home;
- uint64_t P3Home;
- uint64_t P4Home;
- uint64_t P5Home;
- uint64_t P6Home;
- uint32_t ContextFlags;
- uint32_t MxCsr;
- uint16_t SegCs;
- uint16_t SegDs;
- uint16_t SegEs;
- uint16_t SegFs;
- uint16_t SegGs;
- uint16_t SegSs;
- uint32_t EFlags;
- uint64_t Dr0;
- uint64_t Dr1;
- uint64_t Dr2;
- uint64_t Dr3;
- uint64_t Dr6;
- uint64_t Dr7;
- uint64_t Rax;
- uint64_t Rcx;
- uint64_t Rdx;
- uint64_t Rbx;
- uint64_t Rsp;
- uint64_t Rbp;
- uint64_t Rsi;
- uint64_t Rdi;
- uint64_t R8;
- uint64_t R9;
- uint64_t R10;
- uint64_t R11;
- uint64_t R12;
- uint64_t R13;
- uint64_t R14;
- uint64_t R15;
- uint64_t Rip;
- union {
- XMM_SAVE_AREA32_ FltSave;
- struct {
- M128A_ Header[2];
- M128A_ Legacy[8];
- M128A_ Xmm0;
- M128A_ Xmm1;
- M128A_ Xmm2;
- M128A_ Xmm3;
- M128A_ Xmm4;
- M128A_ Xmm5;
- M128A_ Xmm6;
- M128A_ Xmm7;
- M128A_ Xmm8;
- M128A_ Xmm9;
- M128A_ Xmm10;
- M128A_ Xmm11;
- M128A_ Xmm12;
- M128A_ Xmm13;
- M128A_ Xmm14;
- M128A_ Xmm15;
- } DUMMYSTRUCTNAME;
- } DUMMYUNIONNAME;
- M128A_ VectorRegister[26];
- uint64_t VectorControl;
- uint64_t DebugControl;
- uint64_t LastBranchToRip;
- uint64_t LastBranchFromRip;
- uint64_t LastExceptionToRip;
- uint64_t LastExceptionFromRip;
- }; // ContextX86_64
- #ifdef EA_PROCESSOR_X86_64
- struct Context : public ContextX86_64
- {
- // Empty
- };
- #endif
- union DoubleFloat
- {
- double d64;
- float f32[2];
- uint64_t u64;
- uint32_t u32[2];
- };
- /// ContextARM
- ///
- /// Generic ARM processor context.
- /// There are many variations of ARM processors, so one context can't
- /// address them all. We assume an ARM 7 with VFPv3 here, which is the
- /// latest we use as of 2010.
- /// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0041c/ch09s02s02.html
- /// http://www.arm.com/products/processors/technologies/vector-floating-point.php
- ///
- /// mGpr[0] Volatile register. Argument1, return value.
- /// mGpr[1] Volatile register. Argument2, Second 32-bits if double/int Return Value
- /// mGpr[2] Volatile register. Argument3.
- /// mGpr[3] Volatile register. Argument4. Further arguments are put on the stack.
- /// mGpr[4] Permanent register.
- /// mGpr[5] Permanent register.
- /// mGpr[6] Permanent register.
- /// mGpr[7] Permanent register. Thumb instruction set frame pointer.
- /// mGpr[8] Permanent register.
- /// mGpr[9] Permanent register. Has platform-specific uses. On iOS it's reserved for the OS.
- /// mGpr[10] Permanent register. SL (Stack limit, in some uses)
- /// mGpr[11] Permanent register. ARM instruction set frame pointer, except for Apple/iOS where it's general purpose.
- /// mGpr[12] Permanent register. IP (scratch register/new-sb in inter-link-unit calls)
- /// mGpr[13] Permanent register. SP (Stack pointer)
- /// mGpr[14] Permanent register. LR (Link register)
- /// mGpr[15] Permanent register. PC (Program Counter)
- struct ContextARM
- {
- uint32_t mGpr[16]; // General registers.
- uint32_t mCpsr; // Current program status register.
- uint32_t mSpsr; // Saved program status register.
- uint32_t mFpscr; // Floating point status condition register.
- DoubleFloat mDoubleFloat[32]; // If these are present, the device will have either 16 (VFPv3-D16) or 32 (VFPv3-D32) registers.
- }; // ContextARM
- #ifdef EA_PROCESSOR_ARM32
- struct Context : public ContextARM
- {
- // Empty
- };
- #endif
- /// ContextARM64
- ///
- /// Generic ARM64 processor context.
- /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf (page 14)
- /// https://en.wikipedia.org/wiki/Aarch64#AArch64 (optional reading)
- /// http://lxr.free-electrons.com/source/arch/arm64/include/uapi/asm/sigcontext.h
- ///
- /// mGpr[0] Volatile register. Argument1, return value.
- /// mGpr[1] Volatile register. Argument2, Second 32-bits if double/int Return Value (update)
- /// mGpr[2] Volatile register. Argument3.
- /// mGpr[3] Volatile register. Argument4.
- /// mGpr[4] Volatile register. Argument5.
- /// mGpr[5] Volatile register. Argument6.
- /// mGpr[6] Volatile register. Argument7.
- /// mGpr[7] Volatile register. Argument8.
- /// mGpr[8] Permanent register. syscall number is in r8.
- /// mGpr[9] Volatile register. Temporary data.
- /// mGpr[10] Volatile register. Temporary data.
- /// mGpr[11] Volatile register. Temporary data.
- /// mGpr[12] Volatile register. Temporary data.
- /// mGpr[13] Volatile register. Temporary data.
- /// mGpr[14] Volatile register. Temporary data.
- /// mGpr[15] Volatile register. Temporary data.
- /// mGpr[16] Permanent register. IP0 (scratch register/new-sb in inter-link-unit calls)
- /// mGpr[17] Permanent register. IP1 (scratch register/new-sb in inter-link-unit calls)
- /// mGpr[18] Permanent register. Has platform-specific uses. On iOS it's reserved for the OS.
- /// mGpr[19] Callee-saved register.
- /// mGpr[20] Callee-saved register.
- /// mGpr[21] Callee-saved register.
- /// mGpr[22] Callee-saved register.
- /// mGpr[23] Callee-saved register.
- /// mGpr[24] Callee-saved register.
- /// mGpr[25] Callee-saved register.
- /// mGpr[26] Callee-saved register.
- /// mGpr[27] Callee-saved register.
- /// mGpr[28] Callee-saved register.
- /// mGpr[29] Permanent register. FP (Frame pointer)
- /// mGpr[30] Permanent register. LR (Link register)
- /// mGpr[31] Permanent register. SP (Stack pointer)
- ///
- /// Program Counter is not a General Purpose Register
- /// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0801a/BABGHBJC.html
- EA_PREFIX_ALIGN(16)
- struct ContextARM64
- {
- uint64_t mGpr[32]; // General registers.
- uint64_t mPC; // Program counter.
- uint64_t mNzcv; // Global condition register.
- uint32_t mFpsr; // Floating point status register.
- uint32_t mFpcr; // Floating point condition register.
- union
- {
- uint8_t mByteArray [512]; // Access Neon registers as raw bytes.
- double mDoubleArray[512/sizeof(double)]; // Access Neon registers as doubles
- float mFloatArray [512/sizeof(float)]; // Access Neon registers as floats
- uint16_t mUInt16Array[512/sizeof(uint16_t)]; // Access Neon registers as uint16_t's
- uint32_t mUInt32Array[512/sizeof(uint32_t)]; // Access Neon registers as uint32_t's
- uint64_t mUInt64Array[512/sizeof(uint64_t)]; // Access Neon registers as uint64_t's
- } mNeon;
- uint32_t mPadding[2]; // required to avoid warning 4324 on vc
- }EA_POSTFIX_ALIGN(16);// ContextARM64
- #ifdef EA_PROCESSOR_ARM64
- struct Context : public ContextARM64
- {
- // Empty
- };
- #endif
- } // namespace Thread
- } // namespace EA
- EA_RESTORE_VC_WARNING()
- #endif // Header include guard.
|