From e81cc0169eb8bb101ef8755c8c5063fac28e831f Mon Sep 17 00:00:00 2001 From: Josh Peterson Date: Fri, 14 Oct 2016 13:43:31 -0400 Subject: [PATCH 1/2] Handle GetHostByName without a network connection GetHostByName should still work for localhost even when there is no network (e.g. the network cable is unplugged). It should return the proper host name. Since we started supporting IPv6, this was broken. The getaddrinfo function returns a NULL addrinfo value when there is no network. If that happens, fall back to the IPv4-only implementation to try to resolve the host name. This corrects Unity case 840534. --- mono/metadata/socket-io.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/mono/metadata/socket-io.c b/mono/metadata/socket-io.c index fc9c2d255941..8fe03a1ab666 100644 --- a/mono/metadata/socket-io.c +++ b/mono/metadata/socket-io.c @@ -2384,7 +2384,7 @@ get_local_ips (int family, int *nips) #endif /* HAVE_SIOCGIFCONF */ -#ifndef AF_INET6 +#if defined(AF_INET6) && !defined(HAVE_GETHOSTBYNAME2_R) static gboolean hostent_to_IPHostEntry(struct hostent *he, MonoString **h_name, MonoArray **h_aliases, MonoArray **h_addr_list, @@ -2814,11 +2814,13 @@ addrinfo_to_IPHostEntry(struct addrinfo *info, MonoString **h_name, MonoBoolean ves_icall_System_Net_Dns_GetHostByName_internal(MonoString *host, MonoString **h_name, MonoArray **h_aliases, MonoArray **h_addr_list) { gboolean add_local_ips = FALSE; + gboolean result = FALSE; #ifdef HAVE_SIOCGIFCONF gchar this_hostname [256]; #endif #if !defined(HAVE_GETHOSTBYNAME2_R) struct addrinfo *info = NULL, hints; + struct hostent *he; char *hostname; MONO_ARCH_SAVE_REGS; @@ -2841,10 +2843,29 @@ MonoBoolean ves_icall_System_Net_Dns_GetHostByName_internal(MonoString *host, Mo if (*hostname && getaddrinfo(hostname, NULL, &hints, &info) == -1) { return(FALSE); } - - g_free(hostname); - return(addrinfo_to_IPHostEntry(info, h_name, h_aliases, h_addr_list, add_local_ips)); + if (info != NULL) + { + // Prefer parsing the return value from getaddrinfo, as it supports IPv6 correctly. + result = addrinfo_to_IPHostEntry(info, h_name, h_aliases, h_addr_list, add_local_ips); + } + else + { + // If getaddrinfo doesn't give us back anything (maybe the network is down), fall back to + // using a hostent, which should work for IPv4 but does not support IPv6. +#ifndef HOST_WIN32 + he = NULL; + if (*hostname) + he = _wapi_gethostbyname(hostname); +#else + he = _wapi_gethostbyname(hostname); +#endif + + result = hostent_to_IPHostEntry(he, h_name, h_aliases, h_addr_list, add_local_ips); + } + + g_free(hostname); + return result; #else struct hostent he1,*hp1, he2, *hp2; int buffer_size1, buffer_size2; From 10b0731cc18b96c6ae5916a83b72e20de18807fc Mon Sep 17 00:00:00 2001 From: Jonathan Chambers Date: Mon, 17 Oct 2016 07:44:22 -0400 Subject: [PATCH 2/2] Preserve all floating point registers During a context switch, we should preserve all floating point registers. With the new Mono compiler, we're seeing more sequence points, which cause more context switches. If these registers are not preserved, we can have incorrect float values returned when the debugger is attached. These changes correct Unity case 836825. --- mono/mini/exceptions-amd64.c | 114 +++++++++++++++++++++++++++++++++++ mono/mini/mini-amd64.h | 16 +++++ mono/utils/mono-sigcontext.h | 19 ++++++ 3 files changed, 149 insertions(+) diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c index 82762ca40d36..a0e8ba824bf8 100644 --- a/mono/mini/exceptions-amd64.c +++ b/mono/mini/exceptions-amd64.c @@ -168,6 +168,22 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) sctx->r13 = ctx->R13; sctx->r14 = ctx->R14; sctx->r15 = ctx->R15; + sctx->xmm0_low = ctx->Xmm0.Low; + sctx->xmm1_low = ctx->Xmm1.Low; + sctx->xmm2_low = ctx->Xmm2.Low; + sctx->xmm3_low = ctx->Xmm3.Low; + sctx->xmm4_low = ctx->Xmm4.Low; + sctx->xmm5_low = ctx->Xmm5.Low; + sctx->xmm6_low = ctx->Xmm6.Low; + sctx->xmm7_low = ctx->Xmm7.Low; + sctx->xmm8_low = ctx->Xmm8.Low; + sctx->xmm9_low = ctx->Xmm9.Low; + sctx->xmm10_low = ctx->Xmm10.Low; + sctx->xmm11_low = ctx->Xmm11.Low; + sctx->xmm12_low = ctx->Xmm12.Low; + sctx->xmm13_low = ctx->Xmm13.Low; + sctx->xmm14_low = ctx->Xmm14.Low; + sctx->xmm15_low = ctx->Xmm15.Low; switch (er->ExceptionCode) { case EXCEPTION_STACK_OVERFLOW: @@ -218,6 +234,23 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) ctx->R15 = sctx->r15; ctx->Rip = sctx->rip; + ctx->Xmm0.Low = sctx->xmm0_low; + ctx->Xmm1.Low = sctx->xmm1_low; + ctx->Xmm2.Low = sctx->xmm2_low; + ctx->Xmm3.Low = sctx->xmm3_low; + ctx->Xmm4.Low = sctx->xmm4_low; + ctx->Xmm5.Low = sctx->xmm5_low; + ctx->Xmm6.Low = sctx->xmm6_low; + ctx->Xmm7.Low = sctx->xmm7_low; + ctx->Xmm8.Low = sctx->xmm8_low; + ctx->Xmm9.Low = sctx->xmm9_low; + ctx->Xmm10.Low = sctx->xmm10_low; + ctx->Xmm11.Low = sctx->xmm11_low; + ctx->Xmm12.Low = sctx->xmm12_low; + ctx->Xmm13.Low = sctx->xmm13_low; + ctx->Xmm14.Low = sctx->xmm14_low; + ctx->Xmm15.Low = sctx->xmm15_low; + /* Volatile But should not matter?*/ ctx->Rax = sctx->rax; ctx->Rcx = sctx->rcx; @@ -304,6 +337,22 @@ mono_arch_get_restore_context_full (guint32 *code_size, MonoJumpInfo **ji, gbool amd64_mov_reg_membase (code, AMD64_R13, AMD64_R11, G_STRUCT_OFFSET (MonoContext, r13), 8); amd64_mov_reg_membase (code, AMD64_R14, AMD64_R11, G_STRUCT_OFFSET (MonoContext, r14), 8); amd64_mov_reg_membase (code, AMD64_R15, AMD64_R11, G_STRUCT_OFFSET (MonoContext, r15), 8); + amd64_movsd_reg_membase (code, AMD64_XMM0, AMD64_R11, G_STRUCT_OFFSET (MonoContext, xmm0_low)); + amd64_movsd_reg_membase (code, AMD64_XMM1, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm1_low)); + amd64_movsd_reg_membase (code, AMD64_XMM2, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm2_low)); + amd64_movsd_reg_membase (code, AMD64_XMM3, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm3_low)); + amd64_movsd_reg_membase (code, AMD64_XMM4, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm4_low)); + amd64_movsd_reg_membase (code, AMD64_XMM5, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm5_low)); + amd64_movsd_reg_membase (code, AMD64_XMM6, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm6_low)); + amd64_movsd_reg_membase (code, AMD64_XMM7, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm7_low)); + amd64_movsd_reg_membase (code, AMD64_XMM8, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm8_low)); + amd64_movsd_reg_membase (code, AMD64_XMM9, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm9_low)); + amd64_movsd_reg_membase (code, AMD64_XMM10, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm10_low)); + amd64_movsd_reg_membase (code, AMD64_XMM11, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm11_low)); + amd64_movsd_reg_membase (code, AMD64_XMM12, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm12_low)); + amd64_movsd_reg_membase (code, AMD64_XMM13, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm13_low)); + amd64_movsd_reg_membase (code, AMD64_XMM14, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm14_low)); + amd64_movsd_reg_membase (code, AMD64_XMM15, AMD64_R11, G_STRUCT_OFFSET(MonoContext, xmm15_low)); if (mono_running_on_valgrind ()) { /* Prevent 'Address 0x... is just below the stack ptr.' errors */ @@ -935,6 +984,22 @@ mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) mctx->r13 = UCONTEXT_REG_R13 (ctx); mctx->r14 = UCONTEXT_REG_R14 (ctx); mctx->r15 = UCONTEXT_REG_R15 (ctx); + mctx->xmm0_low = UCONTEXT_REG_FPR0_LOW(ctx); + mctx->xmm1_low = UCONTEXT_REG_FPR1_LOW(ctx); + mctx->xmm2_low = UCONTEXT_REG_FPR2_LOW(ctx); + mctx->xmm3_low = UCONTEXT_REG_FPR3_LOW(ctx); + mctx->xmm4_low = UCONTEXT_REG_FPR4_LOW(ctx); + mctx->xmm5_low = UCONTEXT_REG_FPR5_LOW(ctx); + mctx->xmm6_low = UCONTEXT_REG_FPR6_LOW(ctx); + mctx->xmm7_low = UCONTEXT_REG_FPR7_LOW(ctx); + mctx->xmm8_low = UCONTEXT_REG_FPR8_LOW(ctx); + mctx->xmm9_low = UCONTEXT_REG_FPR9_LOW(ctx); + mctx->xmm10_low = UCONTEXT_REG_FPR10_LOW(ctx); + mctx->xmm11_low = UCONTEXT_REG_FPR11_LOW(ctx); + mctx->xmm12_low = UCONTEXT_REG_FPR12_LOW(ctx); + mctx->xmm13_low = UCONTEXT_REG_FPR13_LOW(ctx); + mctx->xmm14_low = UCONTEXT_REG_FPR14_LOW(ctx); + mctx->xmm15_low = UCONTEXT_REG_FPR15_LOW(ctx); #else MonoContext *ctx = (MonoContext *)sigctx; @@ -955,6 +1020,22 @@ mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) mctx->r13 = ctx->r13; mctx->r14 = ctx->r14; mctx->r15 = ctx->r15; + mctx->xmm0_low = ctx->xmm0_low; + mctx->xmm1_low = ctx->xmm1_low; + mctx->xmm2_low = ctx->xmm2_low; + mctx->xmm3_low = ctx->xmm3_low; + mctx->xmm4_low = ctx->xmm4_low; + mctx->xmm5_low = ctx->xmm5_low; + mctx->xmm6_low = ctx->xmm6_low; + mctx->xmm7_low = ctx->xmm7_low; + mctx->xmm8_low = ctx->xmm8_low; + mctx->xmm9_low = ctx->xmm9_low; + mctx->xmm10_low = ctx->xmm10_low; + mctx->xmm11_low = ctx->xmm11_low; + mctx->xmm12_low = ctx->xmm12_low; + mctx->xmm13_low = ctx->xmm13_low; + mctx->xmm14_low = ctx->xmm14_low; + mctx->xmm15_low = ctx->xmm15_low; #endif } @@ -999,6 +1080,23 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) UCONTEXT_REG_R13 (ctx) = mctx->r13; UCONTEXT_REG_R14 (ctx) = mctx->r14; UCONTEXT_REG_R15 (ctx) = mctx->r15; + + UCONTEXT_REG_FPR0_LOW(ctx) = mctx->xmm0_low; + UCONTEXT_REG_FPR1_LOW(ctx) = mctx->xmm1_low; + UCONTEXT_REG_FPR2_LOW(ctx) = mctx->xmm2_low; + UCONTEXT_REG_FPR3_LOW(ctx) = mctx->xmm3_low; + UCONTEXT_REG_FPR4_LOW(ctx) = mctx->xmm4_low; + UCONTEXT_REG_FPR5_LOW(ctx) = mctx->xmm5_low; + UCONTEXT_REG_FPR6_LOW(ctx) = mctx->xmm6_low; + UCONTEXT_REG_FPR7_LOW(ctx) = mctx->xmm7_low; + UCONTEXT_REG_FPR8_LOW(ctx) = mctx->xmm8_low; + UCONTEXT_REG_FPR9_LOW(ctx) = mctx->xmm9_low; + UCONTEXT_REG_FPR10_LOW(ctx) = mctx->xmm10_low; + UCONTEXT_REG_FPR11_LOW(ctx) = mctx->xmm11_low; + UCONTEXT_REG_FPR12_LOW(ctx) = mctx->xmm12_low; + UCONTEXT_REG_FPR13_LOW(ctx) = mctx->xmm13_low; + UCONTEXT_REG_FPR14_LOW(ctx) = mctx->xmm14_low; + UCONTEXT_REG_FPR15_LOW(ctx) = mctx->xmm15_low; #else MonoContext *ctx = (MonoContext *)sigctx; @@ -1019,6 +1117,22 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) ctx->r13 = mctx->r13; ctx->r14 = mctx->r14; ctx->r15 = mctx->r15; + ctx->xmm0_low = mctx->xmm0_low; + ctx->xmm1_low = mctx->xmm1_low; + ctx->xmm2_low = mctx->xmm2_low; + ctx->xmm3_low = mctx->xmm3_low; + ctx->xmm4_low = mctx->xmm4_low; + ctx->xmm5_low = mctx->xmm5_low; + ctx->xmm6_low = mctx->xmm6_low; + ctx->xmm7_low = mctx->xmm7_low; + ctx->xmm8_low = mctx->xmm8_low; + ctx->xmm9_low = mctx->xmm9_low; + ctx->xmm10_low = mctx->xmm10_low; + ctx->xmm11_low = mctx->xmm11_low; + ctx->xmm12_low = mctx->xmm12_low; + ctx->xmm13_low = mctx->xmm13_low; + ctx->xmm14_low = mctx->xmm14_low; + ctx->xmm15_low = mctx->xmm15_low; #endif } diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h index 1e22d0deade0..7f881135f825 100644 --- a/mono/mini/mini-amd64.h +++ b/mono/mini/mini-amd64.h @@ -206,6 +206,22 @@ typedef struct { guint64 r13; guint64 r14; guint64 r15; + guint64 xmm0_low; + guint64 xmm1_low; + guint64 xmm2_low; + guint64 xmm3_low; + guint64 xmm4_low; + guint64 xmm5_low; + guint64 xmm6_low; + guint64 xmm7_low; + guint64 xmm8_low; + guint64 xmm9_low; + guint64 xmm10_low; + guint64 xmm11_low; + guint64 xmm12_low; + guint64 xmm13_low; + guint64 xmm14_low; + guint64 xmm15_low; } MonoContext; #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->rip = (guint64)(ip); } while (0); diff --git a/mono/utils/mono-sigcontext.h b/mono/utils/mono-sigcontext.h index 516cca9d1cfa..9595315ffb9d 100644 --- a/mono/utils/mono-sigcontext.h +++ b/mono/utils/mono-sigcontext.h @@ -106,6 +106,25 @@ #define UCONTEXT_REG_R13(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r13) #define UCONTEXT_REG_R14(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r14) #define UCONTEXT_REG_R15(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r15) + + // The XMM registers are stored as an array of 16 chars, for 128 bits total. We want to use the + // low 64 bits only, so we can cast the start of each register to an unsigned 64-bit integer. + #define UCONTEXT_REG_FPR0_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm0) + #define UCONTEXT_REG_FPR1_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm1) + #define UCONTEXT_REG_FPR2_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm2) + #define UCONTEXT_REG_FPR3_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm3) + #define UCONTEXT_REG_FPR4_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm4) + #define UCONTEXT_REG_FPR5_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm5) + #define UCONTEXT_REG_FPR6_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm6) + #define UCONTEXT_REG_FPR7_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm7) + #define UCONTEXT_REG_FPR8_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm8) + #define UCONTEXT_REG_FPR9_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm9) + #define UCONTEXT_REG_FPR10_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm10) + #define UCONTEXT_REG_FPR11_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm11) + #define UCONTEXT_REG_FPR12_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm12) + #define UCONTEXT_REG_FPR13_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm13) + #define UCONTEXT_REG_FPR14_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm14) + #define UCONTEXT_REG_FPR15_LOW(ctx) *(guint64*)&(((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm15) #elif defined(__FreeBSD__) #define UCONTEXT_GREGS(ctx) ((guint64*)&(((ucontext_t*)(ctx))->uc_mcontext)) #elif defined(__OpenBSD__)