diff options
author | Jan Kotas <jkotas@microsoft.com> | 2017-06-13 05:14:22 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-13 05:14:22 +0300 |
commit | 61b5b72107de609d0ea55375f47f8a7c23902496 (patch) | |
tree | 9b2e2531994f96ca1cb0e462c8825d6bda132cac | |
parent | ecb4e8cffd9b42d82dcbb5a44df4ecc8ea19dd25 (diff) | |
parent | 72f780f9fe1cdafa37e76a378af68d4f378ef004 (diff) |
Merge pull request #3865 from dotnet-bot/from-tfs
Merge changes from TFS
28 files changed, 314 insertions, 156 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs new file mode 100644 index 000000000..6c8c687d9 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs @@ -0,0 +1,32 @@ +// 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. + +using System; + +using Internal.TypeSystem; + +using Internal.Text; + +namespace ILCompiler.DependencyAnalysis +{ + public abstract partial class JumpStubNode : AssemblyStubNode + { + private ISymbolNode _target; + + public ISymbolNode Target + { + get + { + return _target; + } + } + + public JumpStubNode(ISymbolNode target) + { + _target = target; + } + + protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler); + } +} diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NamedJumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NamedJumpStubNode.cs new file mode 100644 index 000000000..e3d4afaa4 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NamedJumpStubNode.cs @@ -0,0 +1,23 @@ +// 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. + +using Internal.Text; + +namespace ILCompiler.DependencyAnalysis +{ + class NamedJumpStubNode : JumpStubNode + { + Utf8String _name; + + public NamedJumpStubNode(string name, ISymbolNode target) : base(target) + { + _name = new Utf8String(name); + } + + public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append(_name); + } + } +} diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs index 1f1b76c3c..2fce7836c 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs @@ -401,7 +401,12 @@ namespace ILCompiler.DependencyAnalysis Debug.Assert(TypeSystemContext.HasEagerStaticConstructor((MetadataType)method.OwningType)); return EagerCctorTable.NewNode(MethodEntrypoint(method)); }); - + + _namedJumpStubNodes = new NodeCache<Tuple<string, ISymbolNode>, NamedJumpStubNode>((Tuple<string, ISymbolNode> id) => + { + return new NamedJumpStubNode(id.Item1, id.Item2); + }); + _vTableNodes = new NodeCache<TypeDesc, VTableSliceNode>((TypeDesc type ) => { if (CompilationModuleGroup.ShouldProduceFullVTable(type)) @@ -934,6 +939,13 @@ namespace ILCompiler.DependencyAnalysis return ReadOnlyDataBlob(symbolName, stringBytes, 1); } + private NodeCache<Tuple<string, ISymbolNode>, NamedJumpStubNode> _namedJumpStubNodes; + + public ISymbolNode NamedJumpStub(string name, ISymbolNode target) + { + return _namedJumpStubNodes.GetOrAdd(new Tuple<string, ISymbolNode>(name, target)); + } + /// <summary> /// Returns alternative symbol name that object writer should produce for given symbols /// in addition to the regular one. diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs index df063a9f8..38dd2edd7 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs @@ -52,11 +52,18 @@ namespace ILCompiler.DependencyAnalysis.ARM // b symbol public void EmitJMP(ISymbolNode symbol) { + Debug.Assert(!symbol.RepresentsIndirectionCell); Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_THUMB_BRANCH24); Builder.EmitByte(0); Builder.EmitByte(0xF0); Builder.EmitByte(0); Builder.EmitByte(0xB8); } + + // bx reg + public void EmitJMP(Register destination) + { + Builder.EmitShort((short)(0x47 | ((byte)destination << 3))); + } } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMJumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMJumpStubNode.cs new file mode 100644 index 000000000..afbc1a662 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMJumpStubNode.cs @@ -0,0 +1,24 @@ +// 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. + +using ILCompiler.DependencyAnalysis.ARM; + +namespace ILCompiler.DependencyAnalysis +{ + public partial class JumpStubNode + { + protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bool relocsOnly) + { + if (!_target.RepresentsIndirectionCell) + { + encoder.EmitJMP(_target); // b methodEntryPoint + } + else + { + encoder.EmitMOV(encoder.TargetRegister.InterproceduralScratch, _target); + encoder.EmitJMP(encoder.TargetRegister.InterproceduralScratch); + } + } + } +} diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs index 5e0fde4fa..6ac115a14 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs @@ -16,12 +16,14 @@ namespace ILCompiler.DependencyAnalysis.ARM public readonly Register Arg0; public readonly Register Arg1; public readonly Register Result; + public readonly Register InterproceduralScratch; public TargetRegisterMap(TargetOS os) { Arg0 = Register.R0; Arg1 = Register.R1; Result = Register.R0; + InterproceduralScratch = Register.R12; } } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs index 3ca448c3f..76c7aa37f 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs @@ -74,8 +74,17 @@ namespace ILCompiler.DependencyAnalysis.X64 public void EmitJMP(ISymbolNode symbol) { - Builder.EmitByte(0xE9); - Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32); + if (symbol.RepresentsIndirectionCell) + { + Builder.EmitByte(0xff); + Builder.EmitByte(0x25); + Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32); + } + else + { + Builder.EmitByte(0xE9); + Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32); + } } public void EmitINT3() diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64JumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64JumpStubNode.cs new file mode 100644 index 000000000..ceaa37150 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64JumpStubNode.cs @@ -0,0 +1,16 @@ +// 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. + +using ILCompiler.DependencyAnalysis.X64; + +namespace ILCompiler.DependencyAnalysis +{ + public partial class JumpStubNode + { + protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bool relocsOnly) + { + encoder.EmitJMP(_target); + } + } +} diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86Emitter.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86Emitter.cs index 72068ff22..b44300b21 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86Emitter.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86Emitter.cs @@ -28,8 +28,17 @@ namespace ILCompiler.DependencyAnalysis.X86 public void EmitJMP(ISymbolNode symbol) { - Builder.EmitByte(0xE9); - Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32); + if (symbol.RepresentsIndirectionCell) + { + Builder.EmitByte(0xff); + Builder.EmitByte(0x25); + Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32); + } + else + { + Builder.EmitByte(0xE9); + Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32); + } } private bool InSignedByteRange(int i) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86JumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86JumpStubNode.cs new file mode 100644 index 000000000..b95bd1a54 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86JumpStubNode.cs @@ -0,0 +1,16 @@ +// 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. + +using ILCompiler.DependencyAnalysis.X86; + +namespace ILCompiler.DependencyAnalysis +{ + public partial class JumpStubNode + { + protected override void EmitCode(NodeFactory factory, ref X86Emitter encoder, bool relocsOnly) + { + encoder.EmitJMP(_target); + } + } +} diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj index 475866398..25de949da 100644 --- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj +++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj @@ -234,6 +234,8 @@ <Compile Include="Compiler\DependencyAnalysis\INodeWithDebugInfo.cs" /> <Compile Include="Compiler\DependencyAnalysis\IExportableSymbolNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\ISymbolNode.cs" /> + <Compile Include="Compiler\DependencyAnalysis\JumpStubNode.cs" /> + <Compile Include="Compiler\DependencyAnalysis\NamedJumpStubNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\NodeFactory.cs" /> <Compile Include="Compiler\DependencyAnalysis\NodeFactory.GenericLookups.cs" /> <Compile Include="Compiler\DependencyAnalysis\NodeFactory.NativeLayout.cs" /> @@ -258,6 +260,7 @@ <Compile Include="Compiler\DependencyAnalysis\VirtualMethodUseNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_X64\Register.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_X64\X64Emitter.cs" /> + <Compile Include="Compiler\DependencyAnalysis\Target_X64\X64JumpStubNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_X64\X64ReadyToRunHelperNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\InterfaceDispatchMapNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_X86\AddrMode.cs" /> @@ -265,12 +268,14 @@ <Compile Include="Compiler\DependencyAnalysis\Target_X86\X86UnboxingStubNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_X86\Register.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_X86\X86Emitter.cs" /> + <Compile Include="Compiler\DependencyAnalysis\Target_X86\X86JumpStubNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_X86\X86ReadyToRunHelperNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_X86\X86ReadyToRunGenericHelperNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_ARM\TargetRegisterMap.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMUnboxingStubNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_ARM\Register.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMEmitter.cs" /> + <Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMJumpStubNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMReadyToRunHelperNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMReadyToRunGenericHelperNode.cs" /> <Compile Include="Compiler\ExportedMethodsRootProvider.cs" /> diff --git a/src/Native/Runtime/StackFrameIterator.cpp b/src/Native/Runtime/StackFrameIterator.cpp index 86de077a1..6899e463d 100644 --- a/src/Native/Runtime/StackFrameIterator.cpp +++ b/src/Native/Runtime/StackFrameIterator.cpp @@ -52,21 +52,21 @@ GVAL_IMPL_INIT(PTR_VOID, g_ReturnFromCallDescrThunkAddr, PointerToReturnFromCall #endif #ifdef _TARGET_X86_ -EXTERN_C void * RhpCallFunclet2; -GVAL_IMPL_INIT(PTR_VOID, g_RhpCallFunclet2Addr, &RhpCallFunclet2); +EXTERN_C void * PointerToRhpCallFunclet2; +GVAL_IMPL_INIT(PTR_VOID, g_RhpCallFunclet2Addr, PointerToRhpCallFunclet2); #endif -EXTERN_C void * RhpCallCatchFunclet2; -GVAL_IMPL_INIT(PTR_VOID, g_RhpCallCatchFunclet2Addr, &RhpCallCatchFunclet2); -EXTERN_C void * RhpCallFinallyFunclet2; -GVAL_IMPL_INIT(PTR_VOID, g_RhpCallFinallyFunclet2Addr, &RhpCallFinallyFunclet2); -EXTERN_C void * RhpCallFilterFunclet2; -GVAL_IMPL_INIT(PTR_VOID, g_RhpCallFilterFunclet2Addr, &RhpCallFilterFunclet2); -EXTERN_C void * RhpThrowEx2; -GVAL_IMPL_INIT(PTR_VOID, g_RhpThrowEx2Addr, &RhpThrowEx2); -EXTERN_C void * RhpThrowHwEx2; -GVAL_IMPL_INIT(PTR_VOID, g_RhpThrowHwEx2Addr, &RhpThrowHwEx2); -EXTERN_C void * RhpRethrow2; -GVAL_IMPL_INIT(PTR_VOID, g_RhpRethrow2Addr, &RhpRethrow2); +EXTERN_C void * PointerToRhpCallCatchFunclet2; +GVAL_IMPL_INIT(PTR_VOID, g_RhpCallCatchFunclet2Addr, PointerToRhpCallCatchFunclet2); +EXTERN_C void * PointerToRhpCallFinallyFunclet2; +GVAL_IMPL_INIT(PTR_VOID, g_RhpCallFinallyFunclet2Addr, PointerToRhpCallFinallyFunclet2); +EXTERN_C void * PointerToRhpCallFilterFunclet2; +GVAL_IMPL_INIT(PTR_VOID, g_RhpCallFilterFunclet2Addr, PointerToRhpCallFilterFunclet2); +EXTERN_C void * PointerToRhpThrowEx2; +GVAL_IMPL_INIT(PTR_VOID, g_RhpThrowEx2Addr, PointerToRhpThrowEx2); +EXTERN_C void * PointerToRhpThrowHwEx2; +GVAL_IMPL_INIT(PTR_VOID, g_RhpThrowHwEx2Addr, PointerToRhpThrowHwEx2); +EXTERN_C void * PointerToRhpRethrow2; +GVAL_IMPL_INIT(PTR_VOID, g_RhpRethrow2Addr, PointerToRhpRethrow2); #endif // !defined(USE_PORTABLE_HELPERS) // Addresses of functions in the DAC won't match their runtime counterparts so we @@ -78,10 +78,8 @@ GVAL_IMPL_INIT(PTR_VOID, g_RhpRethrow2Addr, &RhpRethrow2); // ingest the updated DIA, we're instead exposing a global void * variable // holding the return address. #ifdef DACCESS_COMPILE -#define EQUALS_CODE_ADDRESS(x, func_name) ((x) == g_ ## func_name ## Addr) -#define EQUALS_RETURN_ADDRESS(x, func_name) EQUALS_CODE_ADDRESS((x), func_name) +#define EQUALS_RETURN_ADDRESS(x, func_name) ((x) == g_ ## func_name ## Addr) #else -#define EQUALS_CODE_ADDRESS(x, func_name) ((x) == &func_name) #define EQUALS_RETURN_ADDRESS(x, func_name) (((x)) == (PointerTo ## func_name)) #endif @@ -583,13 +581,13 @@ void StackFrameIterator::UnwindFuncletInvokeThunk() m_ControlPC = dac_cast<PTR_VOID>(*(m_RegDisplay.pIP)); ASSERT( - EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallCatchFunclet2) || - EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallFinallyFunclet2) || - EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallFilterFunclet2) + EQUALS_RETURN_ADDRESS(m_ControlPC, RhpCallCatchFunclet2) || + EQUALS_RETURN_ADDRESS(m_ControlPC, RhpCallFinallyFunclet2) || + EQUALS_RETURN_ADDRESS(m_ControlPC, RhpCallFilterFunclet2) ); #endif - bool isFilterInvoke = EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallFilterFunclet2); + bool isFilterInvoke = EQUALS_RETURN_ADDRESS(m_ControlPC, RhpCallFilterFunclet2); #if defined(UNIX_AMD64_ABI) SP = (PTR_UIntNative)(m_RegDisplay.SP); @@ -608,7 +606,7 @@ void StackFrameIterator::UnwindFuncletInvokeThunk() m_funcletPtrs.pR14 = m_RegDisplay.pR14; m_funcletPtrs.pR15 = m_RegDisplay.pR15; - if (EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallCatchFunclet2)) + if (EQUALS_RETURN_ADDRESS(m_ControlPC, RhpCallCatchFunclet2)) { SP += 6 + 1; // 6 locals and stack alignment } @@ -652,7 +650,7 @@ void StackFrameIterator::UnwindFuncletInvokeThunk() m_funcletPtrs.pR14 = m_RegDisplay.pR14; m_funcletPtrs.pR15 = m_RegDisplay.pR15; - if (EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallCatchFunclet2)) + if (EQUALS_RETURN_ADDRESS(m_ControlPC, RhpCallCatchFunclet2)) { SP += 2 + 1; // 2 locals and stack alignment } @@ -703,7 +701,7 @@ void StackFrameIterator::UnwindFuncletInvokeThunk() { // RhpCallCatchFunclet puts a couple of extra things on the stack that aren't put there by the other two // thunks, but we don't need to know what they are here, so we just skip them. - SP += EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallCatchFunclet2) ? 3 : 1; + SP += EQUALS_RETURN_ADDRESS(m_ControlPC, RhpCallCatchFunclet2) ? 3 : 1; // Save the preserved regs portion of the REGDISPLAY across the unwind through the C# EH dispatch code. m_funcletPtrs.pR4 = m_RegDisplay.pR4; @@ -1623,20 +1621,20 @@ StackFrameIterator::ReturnAddressCategory StackFrameIterator::CategorizeUnadjust } #endif - if (EQUALS_CODE_ADDRESS(returnAddress, RhpThrowEx2) || - EQUALS_CODE_ADDRESS(returnAddress, RhpThrowHwEx2) || - EQUALS_CODE_ADDRESS(returnAddress, RhpRethrow2)) + if (EQUALS_RETURN_ADDRESS(returnAddress, RhpThrowEx2) || + EQUALS_RETURN_ADDRESS(returnAddress, RhpThrowHwEx2) || + EQUALS_RETURN_ADDRESS(returnAddress, RhpRethrow2)) { return InThrowSiteThunk; } if ( #ifdef _TARGET_X86_ - EQUALS_CODE_ADDRESS(returnAddress, RhpCallFunclet2) + EQUALS_RETURN_ADDRESS(returnAddress, RhpCallFunclet2) #else - EQUALS_CODE_ADDRESS(returnAddress, RhpCallCatchFunclet2) || - EQUALS_CODE_ADDRESS(returnAddress, RhpCallFinallyFunclet2) || - EQUALS_CODE_ADDRESS(returnAddress, RhpCallFilterFunclet2) + EQUALS_RETURN_ADDRESS(returnAddress, RhpCallCatchFunclet2) || + EQUALS_RETURN_ADDRESS(returnAddress, RhpCallFinallyFunclet2) || + EQUALS_RETURN_ADDRESS(returnAddress, RhpCallFilterFunclet2) #endif ) { diff --git a/src/Native/Runtime/amd64/AsmMacros.inc b/src/Native/Runtime/amd64/AsmMacros.inc index 4cecf334b..b9835375b 100644 --- a/src/Native/Runtime/amd64/AsmMacros.inc +++ b/src/Native/Runtime/amd64/AsmMacros.inc @@ -215,6 +215,24 @@ Name label proc PUBLIC Name endm +EXPORT_POINTER_TO_ADDRESS macro Name + + local AddressToExport + +AddressToExport label proc + + .const + + align 8 + +Name dq offset AddressToExport + + public Name + + .code + + endm + _tls_array equ 58h ;; offsetof(TEB, ThreadLocalStoragePointer) ;; diff --git a/src/Native/Runtime/amd64/CallDescrWorker.S b/src/Native/Runtime/amd64/CallDescrWorker.S index 6a980b394..a3879d517 100644 --- a/src/Native/Runtime/amd64/CallDescrWorker.S +++ b/src/Native/Runtime/amd64/CallDescrWorker.S @@ -6,17 +6,9 @@ #include <unixasmmacros.inc> NESTED_ENTRY RhCallDescrWorker, _TEXT, NoHandler -LOCAL_LABEL(ReturnFromCallDescrThunk): + + EXPORT_POINTER_TO_ADDRESS PointerToReturnFromCallDescrThunk // UNIXTODO: Implement this function int 3 NESTED_END RhCallDescrWorker, _TEXT - - .text - - .align 8 - -C_FUNC(PointerToReturnFromCallDescrThunk): - .quad LOCAL_LABEL(ReturnFromCallDescrThunk) - - .global C_FUNC(PointerToReturnFromCallDescrThunk) diff --git a/src/Native/Runtime/amd64/CallDescrWorker.asm b/src/Native/Runtime/amd64/CallDescrWorker.asm index a0d07ea45..59d4fb916 100644 --- a/src/Native/Runtime/amd64/CallDescrWorker.asm +++ b/src/Native/Runtime/amd64/CallDescrWorker.asm @@ -57,7 +57,7 @@ StackCopyLoop: ; copy the arguments to stack top-down t DoCall: call qword ptr [rbx + OFFSETOF__CallDescrData__pTarget] ; call target function -ReturnFromCallDescrThunk label proc + EXPORT_POINTER_TO_ADDRESS PointerToReturnFromCallDescrThunk ; Symbol used to identify thunk call to managed function so the special ; case unwinder can unwind through this function. Sadly we cannot directly @@ -103,14 +103,4 @@ ReturnsDouble: NESTED_END RhCallDescrWorker, _TEXT - .const - - align 8 - -PointerToReturnFromCallDescrThunk label qword - - dq offset ReturnFromCallDescrThunk - - public PointerToReturnFromCallDescrThunk - end diff --git a/src/Native/Runtime/amd64/ExceptionHandling.S b/src/Native/Runtime/amd64/ExceptionHandling.S index aa1a59df1..b9478f0a0 100644 --- a/src/Native/Runtime/amd64/ExceptionHandling.S +++ b/src/Native/Runtime/amd64/ExceptionHandling.S @@ -70,7 +70,8 @@ NESTED_ENTRY RhpThrowHwEx, _TEXT, NoHandler // rdi still contains the exception code // rsi contains the address of the ExInfo call C_FUNC(RhThrowHwEx) -ALTERNATE_ENTRY RhpThrowHwEx2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpThrowHwEx2 // no return int 3 @@ -150,7 +151,8 @@ NESTED_ENTRY RhpThrowEx, _TEXT, NoHandler // rdi still contains the exception object // rsi contains the address of the ExInfo call C_FUNC(RhThrowEx) -ALTERNATE_ENTRY RhpThrowEx2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpThrowEx2 // no return int 3 @@ -219,7 +221,8 @@ NESTED_ENTRY RhpRethrow, _TEXT, NoHandler // rdi contains the currently active ExInfo // rsi contains the address of the new ExInfo call C_FUNC(RhRethrow) -ALTERNATE_ENTRY RhpRethrow2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpRethrow2 // no return int 3 @@ -330,7 +333,8 @@ NESTED_ENTRY RhpCallCatchFunclet, _TEXT, NoHandler mov rdi, [rdx + OFFSETOF__REGDISPLAY__SP] // rdi <- establisher frame mov rsi, [rsp + locArg0] // rsi <- exception object call qword ptr [rsp + locArg1] // call handler funclet -ALTERNATE_ENTRY RhpCallCatchFunclet2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpCallCatchFunclet2 mov rdx, [rsp + locArg2] // rdx <- dispatch context @@ -468,7 +472,8 @@ NESTED_ENTRY RhpCallFinallyFunclet, _TEXT, NoHandler mov rdi, [rsi + OFFSETOF__REGDISPLAY__SP] // rdi <- establisher frame call qword ptr [rsp + locArg0] // handler funclet address -ALTERNATE_ENTRY RhpCallFinallyFunclet2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpCallFinallyFunclet2 mov rsi, [rsp + locArg1] // rsi <- regdisplay @@ -517,7 +522,8 @@ NESTED_ENTRY RhpCallFilterFunclet, _TEXT, NoHandler mov rsi, rdi // rsi <- exception object mov rdi, [rdx + OFFSETOF__REGDISPLAY__SP] // rdi <- establisher frame call rax -ALTERNATE_ENTRY RhpCallFilterFunclet2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpCallFilterFunclet2 // RAX contains the result of the filter execution diff --git a/src/Native/Runtime/amd64/ExceptionHandling.asm b/src/Native/Runtime/amd64/ExceptionHandling.asm index a8ba9ef77..ccea8d02d 100644 --- a/src/Native/Runtime/amd64/ExceptionHandling.asm +++ b/src/Native/Runtime/amd64/ExceptionHandling.asm @@ -92,14 +92,14 @@ NESTED_ENTRY RhpThrowHwEx, _TEXT ;; rcx still contains the exception code ;; rdx contains the address of the ExInfo call RhThrowHwEx -ALTERNATE_ENTRY RhpThrowHwEx2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpThrowHwEx2 ;; no return int 3 NESTED_END RhpThrowHwEx, _TEXT - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; RhpThrowEx @@ -184,7 +184,8 @@ NESTED_ENTRY RhpThrowEx, _TEXT ;; rcx still contains the exception object ;; rdx contains the address of the ExInfo call RhThrowEx -ALTERNATE_ENTRY RhpThrowEx2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpThrowEx2 ;; no return int 3 @@ -267,7 +268,8 @@ NESTED_ENTRY RhpRethrow, _TEXT ;; rcx contains the currently active ExInfo ;; rdx contains the address of the new ExInfo call RhRethrow -ALTERNATE_ENTRY RhpRethrow2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpRethrow2 ;; no return int 3 @@ -425,7 +427,8 @@ else mov rcx, [rsp + rsp_offsetof_arguments + 0h] ;; rcx <- exception object endif call qword ptr [rsp + rsp_offsetof_arguments + 8h] ;; call handler funclet -ALTERNATE_ENTRY RhpCallCatchFunclet2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpCallCatchFunclet2 mov r8, [rsp + rsp_offsetof_arguments + 10h] ;; r8 <- dispatch context @@ -584,7 +587,8 @@ endif mov rcx, [rdx + OFFSETOF__REGDISPLAY__SP] ;; rcx <- establisher frame call qword ptr [rsp + rsp_offsetof_arguments + 0h] ;; handler funclet address -ALTERNATE_ENTRY RhpCallFinallyFunclet2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpCallFinallyFunclet2 mov rdx, [rsp + rsp_offsetof_arguments + 8h] ;; rdx <- regdisplay @@ -626,7 +630,6 @@ ALTERNATE_ENTRY RhpCallFinallyFunclet2 NESTED_END RhpCallFinallyFunclet, _TEXT - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; void* FASTCALL RhpCallFilterFunclet(RtuObjectRef exceptionObj, void* pFilterIP, REGDISPLAY* pRegDisplay) @@ -653,7 +656,8 @@ else ;; RCX still contains the exception object endif call rax -ALTERNATE_ENTRY RhpCallFilterFunclet2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpCallFilterFunclet2 ;; RAX contains the result of the filter execution diff --git a/src/Native/Runtime/amd64/UniversalTransition.S b/src/Native/Runtime/amd64/UniversalTransition.S index cf421c630..0f4d0b3ef 100644 --- a/src/Native/Runtime/amd64/UniversalTransition.S +++ b/src/Native/Runtime/amd64/UniversalTransition.S @@ -125,7 +125,7 @@ NESTED_ENTRY Rhp\FunctionName, _TEXT, NoHandler lea rdi, [rsp + DISTANCE_FROM_CHILDSP_TO_RETURN_BLOCK] call r10 -LOCAL_LABEL(ReturnFrom\FunctionName): + EXPORT_POINTER_TO_ADDRESS PointerToReturnFrom\FunctionName // restore fp argument registers movdqa xmm0, [rsp + DISTANCE_FROM_CHILDSP_TO_FP_REGS + 0x00] @@ -152,15 +152,6 @@ LOCAL_LABEL(ReturnFrom\FunctionName): NESTED_END Rhp\FunctionName, _TEXT - .text - - .align 8 - -C_FUNC(PointerToReturnFrom\FunctionName): - .quad LOCAL_LABEL(ReturnFrom\FunctionName) - - .global C_FUNC(PointerToReturnFrom\FunctionName) - .endm // UNIVERSAL_TRANSITION // To enable proper step-in behavior in the debugger, we need to have two instances diff --git a/src/Native/Runtime/amd64/UniversalTransition.asm b/src/Native/Runtime/amd64/UniversalTransition.asm index 83aebaf6d..b582c9729 100644 --- a/src/Native/Runtime/amd64/UniversalTransition.asm +++ b/src/Native/Runtime/amd64/UniversalTransition.asm @@ -127,7 +127,7 @@ endif ; TRASH_SAVED_ARGUMENT_REGISTERS lea rcx, [rsp + DISTANCE_FROM_CHILDSP_TO_RETURN_BLOCK] call r10 -ReturnFrom&FunctionName label proc + EXPORT_POINTER_TO_ADDRESS PointerToReturnFrom&FunctionName ; We cannot make the label public as that tricks DIA stackwalker into thinking ; it's the beginning of a method. For this reason we export the address @@ -155,18 +155,6 @@ ReturnFrom&FunctionName label proc NESTED_END Rhp&FunctionName, _TEXT - .const - - align 8 - -PointerToReturnFrom&FunctionName label qword - - dq offset ReturnFrom&FunctionName - - public PointerToReturnFrom&FunctionName - - .code - endm ; To enable proper step-in behavior in the debugger, we need to have two instances diff --git a/src/Native/Runtime/arm/AsmMacros.h b/src/Native/Runtime/arm/AsmMacros.h index a5735d7b0..e4fbe847e 100644 --- a/src/Native/Runtime/arm/AsmMacros.h +++ b/src/Native/Runtime/arm/AsmMacros.h @@ -189,6 +189,25 @@ $Name MEND + MACRO + EXPORT_POINTER_TO_ADDRESS $Name + +1 + + AREA |.rdata|, ALIGN=4, DATA, READONLY + +$Name + + DCD %BT1 + + EXPORT $Name + + TEXTAREA + + ROUT + + MEND + ;----------------------------------------------------------------------------- ; Macro used to check (in debug builds only) whether the stack is 64-bit aligned (a requirement before calling ; out into C++/OS code). Invoke this directly after your prolog (if the stack frame size is fixed) or directly diff --git a/src/Native/Runtime/arm/CallDescrWorker.asm b/src/Native/Runtime/arm/CallDescrWorker.asm index 656d0e64e..fea7d7f23 100644 --- a/src/Native/Runtime/arm/CallDescrWorker.asm +++ b/src/Native/Runtime/arm/CallDescrWorker.asm @@ -59,8 +59,7 @@ LNoFloatingPoint ldr r4, [r5,#OFFSETOF__CallDescrData__pTarget] blx r4 -ReturnFromCallDescrThunk - rout + EXPORT_POINTER_TO_ADDRESS PointerToReturnFromCallDescrThunk ;; Symbol used to identify thunk call to managed function so the special ;; case unwinder can unwind through this function. Sadly we cannot directly @@ -127,12 +126,4 @@ LReturnDone NESTED_END RhCallDescrWorker - AREA |.rdata|, ALIGN=4, DATA, READONLY - -PointerToReturnFromCallDescrThunk - - DCD ReturnFromCallDescrThunk - - EXPORT PointerToReturnFromCallDescrThunk - END diff --git a/src/Native/Runtime/arm/ExceptionHandling.asm b/src/Native/Runtime/arm/ExceptionHandling.asm index 1cfc89f5b..b8b2f396c 100644 --- a/src/Native/Runtime/arm/ExceptionHandling.asm +++ b/src/Native/Runtime/arm/ExceptionHandling.asm @@ -70,14 +70,14 @@ ;; r0: exception code ;; r1: ExInfo* bl RhThrowHwEx - LABELED_RETURN_ADDRESS RhpThrowHwEx2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpThrowHwEx2 ;; no return __debugbreak NESTED_END RhpThrowHwEx - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; RhpThrowEx @@ -172,14 +172,14 @@ NotHijacked ;; r0: exception object ;; r1: ExInfo* bl RhThrowEx - LABELED_RETURN_ADDRESS RhpThrowEx2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpThrowEx2 ;; no return __debugbreak NESTED_END RhpThrowEx - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; void FASTCALL RhpRethrow() @@ -229,7 +229,8 @@ NotHijacked ;; r0 contains the currently active ExInfo ;; r1 contains the address of the new ExInfo bl RhRethrow - LABELED_RETURN_ADDRESS RhpRethrow2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpRethrow2 ;; no return __debugbreak @@ -323,7 +324,8 @@ ClearSuccess_Catch ;; ;; r0 still contains the exception object blx r1 - LABELED_RETURN_ADDRESS RhpCallCatchFunclet2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpCallCatchFunclet2 ;; r0 contains resume IP @@ -355,7 +357,6 @@ DonePopping NESTED_END RhpCallCatchFunclet - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; void FASTCALL RhpCallFinallyFunclet(void* pHandlerIP, REGDISPLAY* pRegDisplay) @@ -446,7 +447,8 @@ ClearSuccess ;; call the funclet ;; blx r0 - LABELED_RETURN_ADDRESS RhpCallFinallyFunclet2 + + EXPORT_POINTER_TO_ADDRESS PointerToRhpCallFinallyFunclet2 ldr r1, [sp, #rsp_offset_r1] ;; reload REGDISPLAY pointer @@ -495,7 +497,6 @@ SetSuccess INLINE_GETTHREAD_CONSTANT_POOL - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; void* FASTCALL RhpCallFilterFunclet(RtuObjectRef exceptionObj, void* pFilterIP, REGDISPLAY* pRegDisplay) @@ -520,13 +521,12 @@ SetSuccess ;; ;; r0 still contains the exception object blx r1 - LABELED_RETURN_ADDRESS RhpCallFilterFunclet2 + EXPORT_POINTER_TO_ADDRESS PointerToRhpCallFilterFunclet2 EPILOG_VPOP {d8-d15} EPILOG_POP {r4-r11,pc} NESTED_END RhpCallFilterFunclet - end diff --git a/src/Native/Runtime/arm/UniversalTransition.asm b/src/Native/Runtime/arm/UniversalTransition.asm index 6b6240313..fffb3b4ea 100644 --- a/src/Native/Runtime/arm/UniversalTransition.asm +++ b/src/Native/Runtime/arm/UniversalTransition.asm @@ -124,9 +124,7 @@ add r0, sp, #DISTANCE_FROM_CHILDSP_TO_RETURN_BLOCK ;; First parameter to target function is a pointer to the return block blx r12 -ReturnFrom$FunctionName - - rout + EXPORT_POINTER_TO_ADDRESS PointerToReturnFrom$FunctionName ; We cannot make the label public as that tricks DIA stackwalker into thinking ; it's the beginning of a method. For this reason we export an auxiliary variable @@ -149,14 +147,6 @@ ReturnFrom$FunctionName NESTED_END Rhp$FunctionName - AREA |.rdata|, ALIGN=4, DATA, READONLY - -PointerToReturnFrom$FunctionName - - DCD ReturnFrom$FunctionName - - EXPORT PointerToReturnFrom$FunctionName - MEND ; To enable proper step-in behavior in the debugger, we need to have two instances diff --git a/src/Native/Runtime/i386/AsmMacros.inc b/src/Native/Runtime/i386/AsmMacros.inc index ab09d7fd8..2c305c3f0 100644 --- a/src/Native/Runtime/i386/AsmMacros.inc +++ b/src/Native/Runtime/i386/AsmMacros.inc @@ -35,6 +35,24 @@ decoratedName label proc PUBLIC decoratedName endm +EXPORT_POINTER_TO_ADDRESS macro Name + + local AddressToExport + +AddressToExport label proc + + .const + + align 4 + +Name dd offset AddressToExport + + public Name + + .code + + endm + __tls_array equ 2Ch ;; offsetof(TEB, ThreadLocalStoragePointer) ;; diff --git a/src/Native/Runtime/i386/CallDescrWorker.asm b/src/Native/Runtime/i386/CallDescrWorker.asm index f73bb9b64..cc4262c5e 100644 --- a/src/Native/Runtime/i386/CallDescrWorker.asm +++ b/src/Native/Runtime/i386/CallDescrWorker.asm @@ -49,7 +49,7 @@ donestack: mov eax,[ebx + OFFSETOF__CallDescrData__pTarget] call eax -ReturnFromCallDescrThunk label proc + EXPORT_POINTER_TO_ADDRESS _PointerToReturnFromCallDescrThunk ; Symbol used to identify thunk call to managed function so the special ; case unwinder can unwind through this function. Sadly we cannot directly @@ -92,16 +92,6 @@ ReturnsDouble: FASTCALL_ENDFUNC - .const - - align 4 - -_PointerToReturnFromCallDescrThunk label dword - - dd offset ReturnFromCallDescrThunk - - public _PointerToReturnFromCallDescrThunk - endif end diff --git a/src/Native/Runtime/i386/ExceptionHandling.asm b/src/Native/Runtime/i386/ExceptionHandling.asm index d96ed44b8..d8c4653fb 100644 --- a/src/Native/Runtime/i386/ExceptionHandling.asm +++ b/src/Native/Runtime/i386/ExceptionHandling.asm @@ -72,7 +72,8 @@ FASTCALL_FUNC RhpThrowHwEx, 0 ;; ecx still contains the exception code ;; edx contains the address of the ExInfo call RhThrowHwEx -ALTERNATE_ENTRY RhpThrowHwEx2 + + EXPORT_POINTER_TO_ADDRESS _PointerToRhpThrowHwEx2 ;; no return int 3 @@ -148,7 +149,8 @@ FASTCALL_FUNC RhpThrowEx, 0 ;; ecx still contains the exception object ;; edx contains the address of the ExInfo call RhThrowEx -ALTERNATE_ENTRY RhpThrowEx2 + + EXPORT_POINTER_TO_ADDRESS _PointerToRhpThrowEx2 ;; no return int 3 @@ -216,7 +218,8 @@ FASTCALL_FUNC RhpRethrow, 0 ;; ecx contains the currently active ExInfo ;; edx contains the address of the new ExInfo call RhRethrow -ALTERNATE_ENTRY RhpRethrow2 + + EXPORT_POINTER_TO_ADDRESS _PointerToRhpRethrow2 ;; no return int 3 @@ -305,7 +308,8 @@ FASTCALL_FUNC RhpCallCatchFunclet, 0 ;; EDX: funclet IP ;; EAX: funclet EBP call RhpCallFunclet -ALTERNATE_ENTRY RhpCallCatchFunclet2 + + EXPORT_POINTER_TO_ADDRESS _PointerToRhpCallCatchFunclet2 ;; eax: resume IP mov [esp + esp_offsetof_ResumeIP], eax ;; save for later @@ -381,7 +385,8 @@ FASTCALL_FUNC RhpCallFinallyFunclet, 0 ;; EDX: funclet IP ;; EAX: funclet EBP call RhpCallFunclet -ALTERNATE_ENTRY RhpCallFinallyFunclet2 + + EXPORT_POINTER_TO_ADDRESS _PointerToRhpCallFinallyFunclet2 pop edx ;; restore REGDISPLAY* @@ -434,7 +439,8 @@ FASTCALL_FUNC RhpCallFilterFunclet, 0 mov edx, [esp + 0] ;; reload filter funclet address call RhpCallFunclet -ALTERNATE_ENTRY RhpCallFilterFunclet2 + + EXPORT_POINTER_TO_ADDRESS _PointerToRhpCallFilterFunclet2 ;; EAX contains the result of the filter execution mov edx, [ebp + 8] diff --git a/src/Native/Runtime/i386/UniversalTransition.asm b/src/Native/Runtime/i386/UniversalTransition.asm index 9ee597ea7..4d51398da 100644 --- a/src/Native/Runtime/i386/UniversalTransition.asm +++ b/src/Native/Runtime/i386/UniversalTransition.asm @@ -74,7 +74,8 @@ ALTERNATE_ENTRY Rhp&FunctionName&@0 mov edx, [ebp-4] ; Get the extra argument to pass to the callee lea ecx, [ebp-10h] ; Get pointer to edx value pushed above call eax -ReturnFrom&FunctionName label proc + + EXPORT_POINTER_TO_ADDRESS _PointerToReturnFrom&FunctionName ; We cannot make the label public as that tricks DIA stackwalker into thinking ; it's the beginning of a method. For this reason we export an auxiliary variable @@ -88,18 +89,6 @@ ReturnFrom&FunctionName label proc FASTCALL_ENDFUNC - .const - - align 4 - -_PointerToReturnFrom&FunctionName label dword - - dd offset ReturnFrom&FunctionName - - public _PointerToReturnFrom&FunctionName - - .code - endm ; To enable proper step-in behavior in the debugger, we need to have two instances diff --git a/src/Native/Runtime/unix/unixasmmacrosamd64.inc b/src/Native/Runtime/unix/unixasmmacrosamd64.inc index ed6f1db30..1b79e44fc 100644 --- a/src/Native/Runtime/unix/unixasmmacrosamd64.inc +++ b/src/Native/Runtime/unix/unixasmmacrosamd64.inc @@ -222,6 +222,19 @@ C_FUNC(\Name): .endm +.macro EXPORT_POINTER_TO_ADDRESS Name + +1: + + .data + .align 8 +C_FUNC(\Name): + .quad 1b + .global C_FUNC(\Name) + .text + +.endm + // // CONSTANTS -- INTEGER // |