PDataManager.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. #include "Backend.h"
  6. // Conditionally-compiled on x64 and arm
  7. #if PDATA_ENABLED
  8. #ifdef _WIN32
  9. // ----------------------------------------------------------------------------
  10. // _WIN32 x64 unwind uses PDATA
  11. // ----------------------------------------------------------------------------
  12. void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart, _In_ const ULONG_PTR functionStart, _In_ const ULONG_PTR functionEnd, _Out_ PVOID* pdataTable, ULONG entryCount, ULONG maxEntryCount)
  13. {
  14. BOOLEAN success = FALSE;
  15. if (AutoSystemInfo::Data.IsWin8OrLater())
  16. {
  17. Assert(pdataTable != NULL);
  18. // Since we do not expect many thunk functions to be created, we are using 1 table/function
  19. // for now. This can be optimized further if needed.
  20. DWORD status = NtdllLibrary::Instance->AddGrowableFunctionTable(pdataTable,
  21. pdataStart,
  22. entryCount,
  23. maxEntryCount,
  24. /*RangeBase*/ functionStart,
  25. /*RangeEnd*/ functionEnd);
  26. success = NT_SUCCESS(status);
  27. if (success)
  28. {
  29. Assert(pdataTable);
  30. }
  31. }
  32. else
  33. {
  34. *pdataTable = pdataStart;
  35. success = RtlAddFunctionTable(pdataStart, entryCount, functionStart);
  36. }
  37. Js::Throw::CheckAndThrowOutOfMemory(success);
  38. }
  39. void PDataManager::UnregisterPdata(RUNTIME_FUNCTION* pdata)
  40. {
  41. if (AutoSystemInfo::Data.IsWin8OrLater())
  42. {
  43. NtdllLibrary::Instance->DeleteGrowableFunctionTable(pdata);
  44. }
  45. else
  46. {
  47. BOOLEAN success = RtlDeleteFunctionTable(pdata);
  48. Assert(success);
  49. }
  50. }
  51. #else // !_WIN32
  52. // ----------------------------------------------------------------------------
  53. // !_WIN32 x64 unwind uses .eh_frame
  54. // ----------------------------------------------------------------------------
  55. void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart, _In_ const ULONG_PTR functionStart, _In_ const ULONG_PTR functionEnd, _Out_ PVOID* pdataTable, ULONG entryCount, ULONG maxEntryCount)
  56. {
  57. __register_frame(pdataStart);
  58. *pdataTable = pdataStart;
  59. }
  60. void PDataManager::UnregisterPdata(RUNTIME_FUNCTION* pdata)
  61. {
  62. __deregister_frame(pdata);
  63. }
  64. #endif // !_WIN32
  65. #endif // PDATA_ENABLED