diff --git a/src/Native/Runtime/i386/MiscStubs.S b/src/Native/Runtime/i386/MiscStubs.S index ae88c7b3748..4af532e7439 100644 --- a/src/Native/Runtime/i386/MiscStubs.S +++ b/src/Native/Runtime/i386/MiscStubs.S @@ -2,6 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +.intel_syntax noprefix +#include + // *********************************************************************/ // JIT_StackProbe // diff --git a/src/Native/Runtime/unix/UnixContext.cpp b/src/Native/Runtime/unix/UnixContext.cpp index cb8994a9c4e..1e6e498b3ce 100644 --- a/src/Native/Runtime/unix/UnixContext.cpp +++ b/src/Native/Runtime/unix/UnixContext.cpp @@ -270,6 +270,10 @@ static void RegDisplayToUnwindCursor(REGDISPLAY* regDisplay, unw_cursor_t *curso ASSIGN_REG_PTR(UNW_ARM64_X26, X26) ASSIGN_REG_PTR(UNW_ARM64_X27, X27) ASSIGN_REG_PTR(UNW_ARM64_X28, X28) +#elif defined(_X86_) + ASSIGN_REG(UNW_REG_SP, SP) + ASSIGN_REG_PTR(UNW_X86_EBP, Rbp) + ASSIGN_REG_PTR(UNW_X86_EBX, Rbx) #endif #undef ASSIGN_REG @@ -301,6 +305,8 @@ bool GetUnwindProcInfo(PCODE ip, unw_proc_info_t *procInfo) ((uint32_t*)(unwContext.data))[32] = ip; #elif _WASM_ ASSERT(false); +#elif _X86_ + ASSERT(false); #else #error "GetUnwindProcInfo is not supported on this arch yet." #endif @@ -342,6 +348,8 @@ bool InitializeUnwindContextAndCursor(REGDISPLAY* regDisplay, unw_cursor_t* curs ((uint32_t*)(unwContext->data))[15] = regDisplay->IP; #elif _ARM64_ ((uint32_t*)(unwContext->data))[32] = regDisplay->IP; +#elif _X86_ + ASSERT(false); #else #error "InitializeUnwindContextAndCursor is not supported on this arch yet." #endif diff --git a/src/Native/Runtime/unix/UnwindHelpers.cpp b/src/Native/Runtime/unix/UnwindHelpers.cpp index 56845d1b3fd..03ce8ce5430 100644 --- a/src/Native/Runtime/unix/UnwindHelpers.cpp +++ b/src/Native/Runtime/unix/UnwindHelpers.cpp @@ -33,6 +33,8 @@ using libunwind::Registers_x86_64; using libunwind::Registers_arm; #elif defined(_TARGET_ARM64_) using libunwind::Registers_arm64; +#elif defined(_TARGET_X86_) +using libunwind::Registers_x86; #else #error "Unwinding is not implemented for this architecture yet." #endif @@ -214,6 +216,124 @@ struct Registers_REGDISPLAY : REGDISPLAY }; #endif // _TARGET_AMD64_ +#if defined(_TARGET_X86_) +struct Registers_REGDISPLAY : REGDISPLAY +{ + static int getArch() { return libunwind::REGISTERS_X86; } + + inline uint64_t getRegister(int regNum) const + { + switch (regNum) + { + case UNW_REG_IP: + return IP; + case UNW_REG_SP: + return SP; + case UNW_X86_EAX: + return *pRax; + case UNW_X86_EDX: + return *pRdx; + case UNW_X86_ECX: + return *pRcx; + case UNW_X86_EBX: + return *pRbx; + case UNW_X86_ESI: + return *pRsi; + case UNW_X86_EDI: + return *pRdi; + case UNW_X86_EBP: + return *pRbp; + case UNW_X86_ESP: + return SP; + } + + // Unsupported register requested + abort(); + } + + inline void setRegister(int regNum, uint64_t value, uint64_t location) + { + switch (regNum) + { + case UNW_REG_IP: + IP = value; + pIP = (PTR_PCODE)location; + return; + case UNW_REG_SP: + SP = value; + return; + case UNW_X86_EAX: + pRax = (PTR_UIntNative)location; + return; + case UNW_X86_EDX: + pRdx = (PTR_UIntNative)location; + return; + case UNW_X86_ECX: + pRcx = (PTR_UIntNative)location; + return; + case UNW_X86_EBX: + pRbx = (PTR_UIntNative)location; + return; + case UNW_X86_ESI: + pRsi = (PTR_UIntNative)location; + return; + case UNW_X86_EDI: + pRdi = (PTR_UIntNative)location; + return; + case UNW_X86_EBP: + pRbp = (PTR_UIntNative)location; + return; + case UNW_X86_ESP: + SP = value; + return; + } + + // Unsupported x86_64 register + abort(); + } + + // N/A for x86 + inline bool validFloatRegister(int) { return false; } + inline bool validVectorRegister(int) { return false; } + + inline static int lastDwarfRegNum() { return 16; } + + inline bool validRegister(int regNum) const + { + if (regNum == UNW_REG_IP) + return true; + if (regNum == UNW_REG_SP) + return true; + if (regNum < 0) + return false; + if (regNum > 15) + return false; + return true; + } + + // N/A for x86 + inline double getFloatRegister(int) const { abort(); } + inline void setFloatRegister(int, double) { abort(); } + inline double getVectorRegister(int) const { abort(); } + inline void setVectorRegister(int, ...) { abort(); } + + void setSP(uint64_t value, uint64_t location) { SP = value; } + + uint64_t getIP() const { return IP; } + + void setIP(uint64_t value, uint64_t location) + { + IP = value; + pIP = (PTR_PCODE)location; + } + + uint64_t getEBP() const { return *pRbp; } + void setEBP(uint64_t value, uint64_t location) { pRbp = (PTR_UIntNative)location; } + uint64_t getEBX() const { return *pRbx; } + void setEBX(uint64_t value, uint64_t location) { pRbx = (PTR_UIntNative)location; } +}; + +#endif // _TARGET_X86_ #if defined(_TARGET_ARM_) class Registers_arm_rt: public libunwind::Registers_arm { @@ -589,6 +709,8 @@ bool DoTheStep(uintptr_t pc, UnwindInfoSections uwInfoSections, REGDISPLAY *regs libunwind::UnwindCursor uc(_addressSpace, regs); #elif defined(_TARGET_ARM64_) libunwind::UnwindCursor uc(_addressSpace, regs); +#elif defined(_X86_) + libunwind::UnwindCursor uc(_addressSpace, regs); #else #error "Unwinding is not implemented for this architecture yet." #endif diff --git a/src/Native/Runtime/unix/unixasmmacros.inc b/src/Native/Runtime/unix/unixasmmacros.inc index b18fbd28630..99f6e22cd04 100644 --- a/src/Native/Runtime/unix/unixasmmacros.inc +++ b/src/Native/Runtime/unix/unixasmmacros.inc @@ -33,4 +33,6 @@ #include "unixasmmacrosarm.inc" #elif defined(_ARM64_) #include "unixasmmacrosarm64.inc" +#elif defined(_X86_) +#include "unixasmmacrosx86.inc" #endif diff --git a/src/Native/Runtime/unix/unixasmmacrosx86.inc b/src/Native/Runtime/unix/unixasmmacrosx86.inc new file mode 100644 index 00000000000..7730505bc3c --- /dev/null +++ b/src/Native/Runtime/unix/unixasmmacrosx86.inc @@ -0,0 +1,118 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.macro NESTED_ENTRY Name, Section, Handler + LEAF_ENTRY \Name, \Section + .ifnc \Handler, NoHandler + .cfi_personality 0x1b, C_FUNC(\Handler) // 0x1b == DW_EH_PE_pcrel | DW_EH_PE_sdata4 + .endif +.endm + +.macro NESTED_END Name, Section + LEAF_END \Name, \Section +.endm + +.macro LEAF_ENTRY Name, Section + .global C_FUNC(\Name) + .type \Name, %function +C_FUNC(\Name): + .cfi_startproc +.endm + +.macro PATCH_LABEL Name + .global C_FUNC(\Name) +C_FUNC(\Name): +.endm + +.macro LEAF_END Name, Section + .size \Name, .-\Name + .cfi_endproc +.endm + +.macro LEAF_END_MARKED Name, Section +C_FUNC(\Name\()_End): + .global C_FUNC(\Name\()_End) + LEAF_END \Name, \Section +.endm + +.macro PROLOG_BEG + push ebp + .cfi_def_cfa_offset 8 + .cfi_offset ebp, -8 + mov ebp, esp +.endm + +.macro PROLOG_PUSH Reg + push \Reg + .cfi_adjust_cfa_offset 4 + .cfi_rel_offset \Reg, 0 +.endm + +.macro PROLOG_END + .cfi_def_cfa_register ebp + .cfi_def_cfa_offset 8 +.endm + +.macro EPILOG_BEG +.endm + +.macro EPILOG_POP Reg + pop \Reg + .cfi_restore \Reg +.endm + +.macro EPILOG_END + pop ebp +.endm + +.macro ESP_PROLOG_BEG +.endm + +.macro ESP_PROLOG_PUSH Reg + PROLOG_PUSH \Reg +.endm + +.macro ESP_PROLOG_ALLOC Size + sub esp, \Size + .cfi_adjust_cfa_offset \Size +.endm + +.macro ESP_PROLOG_END + .cfi_def_cfa_register esp +.endm + +.macro ESP_EPILOG_BEG +.endm + +.macro ESP_EPILOG_POP Reg + EPILOG_POP \Reg +.endm + +.macro ESP_EPILOG_FREE Size + add esp, \Size + .cfi_adjust_cfa_offset -\Size +.endm + +.macro ESP_EPILOG_END +.endm + +.macro PREPARE_EXTERNAL_VAR Name, Reg +.att_syntax + call 0f +0: + popl %\Reg +1: + addl $_GLOBAL_OFFSET_TABLE_ + (1b - 0b), %\Reg + movl C_FUNC(\Name)@GOT(%\Reg), %\Reg +.intel_syntax noprefix +.endm + +.macro CHECK_STACK_ALIGNMENT +#ifdef _DEBUG + test esp, 0Fh + je 0f + int3 +0: +#endif // _DEBUG +.endm diff --git a/src/Native/System.Private.TypeLoader.Native/i386/ConstrainedCallSupportHelpers.S b/src/Native/System.Private.TypeLoader.Native/i386/ConstrainedCallSupportHelpers.S new file mode 100644 index 00000000000..1dc275673fe --- /dev/null +++ b/src/Native/System.Private.TypeLoader.Native/i386/ConstrainedCallSupportHelpers.S @@ -0,0 +1,5 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// TODO: Implement diff --git a/src/Native/System.Private.TypeLoader.Native/i386/MethodEntrypointStubs.S b/src/Native/System.Private.TypeLoader.Native/i386/MethodEntrypointStubs.S new file mode 100644 index 00000000000..1dc275673fe --- /dev/null +++ b/src/Native/System.Private.TypeLoader.Native/i386/MethodEntrypointStubs.S @@ -0,0 +1,5 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// TODO: Implement diff --git a/src/Native/System.Private.TypeLoader.Native/i386/VTableResolver.S b/src/Native/System.Private.TypeLoader.Native/i386/VTableResolver.S new file mode 100644 index 00000000000..1dc275673fe --- /dev/null +++ b/src/Native/System.Private.TypeLoader.Native/i386/VTableResolver.S @@ -0,0 +1,5 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// TODO: Implement diff --git a/src/Native/libunwind/include/__libunwind_config.h b/src/Native/libunwind/include/__libunwind_config.h index 871ca33e760..41f3fc7802b 100644 --- a/src/Native/libunwind/include/__libunwind_config.h +++ b/src/Native/libunwind/include/__libunwind_config.h @@ -28,7 +28,7 @@ # if defined(__i386__) # define _LIBUNWIND_TARGET_I386 # define _LIBUNWIND_CONTEXT_SIZE 13 -# define _LIBUNWIND_CURSOR_SIZE 23 +# define _LIBUNWIND_CURSOR_SIZE 19 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 # elif defined(__x86_64__) # define _LIBUNWIND_TARGET_X86_64 1