Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
Fix x86 Native build on Unix (#7899)
Browse files Browse the repository at this point in the history
  • Loading branch information
am11 authored and jkotas committed Dec 3, 2019
1 parent 8a17640 commit 180a175
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/Native/Runtime/i386/MiscStubs.S
Original file line number Diff line number Diff line change
Expand Up @@ -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 <unixasmmacros.inc>

// *********************************************************************/
// JIT_StackProbe
//
Expand Down
8 changes: 8 additions & 0 deletions src/Native/Runtime/unix/UnixContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
122 changes: 122 additions & 0 deletions src/Native/Runtime/unix/UnwindHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -589,6 +709,8 @@ bool DoTheStep(uintptr_t pc, UnwindInfoSections uwInfoSections, REGDISPLAY *regs
libunwind::UnwindCursor<LocalAddressSpace, Registers_arm_rt> uc(_addressSpace, regs);
#elif defined(_TARGET_ARM64_)
libunwind::UnwindCursor<LocalAddressSpace, Registers_arm64_rt> uc(_addressSpace, regs);
#elif defined(_X86_)
libunwind::UnwindCursor<LocalAddressSpace, Registers_x86> uc(_addressSpace, regs);
#else
#error "Unwinding is not implemented for this architecture yet."
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/Native/Runtime/unix/unixasmmacros.inc
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@
#include "unixasmmacrosarm.inc"
#elif defined(_ARM64_)
#include "unixasmmacrosarm64.inc"
#elif defined(_X86_)
#include "unixasmmacrosx86.inc"
#endif
118 changes: 118 additions & 0 deletions src/Native/Runtime/unix/unixasmmacrosx86.inc
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion src/Native/libunwind/include/__libunwind_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 180a175

Please sign in to comment.