JITThunkEmitter.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. #if defined(ENABLE_NATIVE_CODEGEN) && defined(_CONTROL_FLOW_GUARD) && (_M_IX86 || _M_X64)
  7. template <typename TAlloc>
  8. class JITThunkEmitter
  9. {
  10. private:
  11. static const BYTE DirectJmp[];
  12. static const uint DirectJmpTargetOffset = 1;
  13. static const uint DirectJmpIPAdjustment = 5;
  14. #if _M_AMD64
  15. static const BYTE IndirectJmp[];
  16. static const uint IndirectJmpTargetOffset = 2;
  17. #endif
  18. static const uint PageCount = 100;
  19. static const size_t ThunkSize = 16;
  20. static const size_t ThunksPerPage = AutoSystemInfo::PageSize / ThunkSize;
  21. public:
  22. static const uintptr_t ThunkAlignmentMask = ~(ThunkSize-1);
  23. static const uint TotalThunkSize = AutoSystemInfo::PageSize * PageCount;
  24. static const size_t TotalThunkCount = TotalThunkSize / ThunkSize;
  25. private:
  26. CriticalSection cs;
  27. TAlloc * codeAllocator;
  28. uintptr_t baseAddress;
  29. HANDLE processHandle;
  30. BVStatic<TotalThunkCount> freeThunks;
  31. ThreadContextInfo * threadContext;
  32. BVIndex firstBitToCheck;
  33. public:
  34. JITThunkEmitter(ThreadContextInfo * threadContext, TAlloc * codeAllocator, HANDLE processHandle);
  35. ~JITThunkEmitter();
  36. uintptr_t CreateThunk(uintptr_t entryPoint);
  37. void FreeThunk(uintptr_t thunkAddress);
  38. uintptr_t EnsureInitialized();
  39. bool IsInThunk(uintptr_t address) const;
  40. static bool IsInThunk(uintptr_t thunkBaseAddress, uintptr_t address);
  41. private:
  42. uintptr_t GetThunkAddressFromIndex(BVIndex index) const;
  43. BVIndex GetThunkIndexFromAddress(uintptr_t index) const;
  44. void ProtectPage(void * address);
  45. void UnprotectPage(void * address);
  46. bool IsThunkPageEmpty(uintptr_t address) const;
  47. static void EncodeJmp(char * localPageAddress, uintptr_t thunkAddress, uintptr_t targetAddress);
  48. static uintptr_t GetThunkPageStart(uintptr_t address);
  49. };
  50. #if ENABLE_OOP_NATIVE_CODEGEN
  51. typedef JITThunkEmitter<SectionAllocWrapper> OOPJITThunkEmitter;
  52. #endif
  53. typedef JITThunkEmitter<VirtualAllocWrapper> InProcJITThunkEmitter;
  54. #endif