PDataManager.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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/arm64
  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. HRESULT hr = S_OK;
  16. if (AutoSystemInfo::Data.IsWin8OrLater())
  17. {
  18. Assert(pdataTable != NULL);
  19. // Since we do not expect many thunk functions to be created, we are using 1 table/function
  20. // for now. This can be optimized further if needed.
  21. NTSTATUS status = NtdllLibrary::Instance->AddGrowableFunctionTable(pdataTable,
  22. pdataStart,
  23. entryCount,
  24. maxEntryCount,
  25. /*RangeBase*/ functionStart,
  26. /*RangeEnd*/ functionEnd);
  27. success = NT_SUCCESS(status);
  28. Assert(!success || pdataTable);
  29. hr = status;
  30. }
  31. else
  32. {
  33. *pdataTable = pdataStart;
  34. success = RtlAddFunctionTable(pdataStart, entryCount, functionStart);
  35. if (!success)
  36. {
  37. hr = E_OUTOFMEMORY; // only OOM error can happen for RtlAddFunctionTable
  38. }
  39. }
  40. if (!success)
  41. {
  42. Js::Throw::XDataRegistrationError(hr, functionStart);
  43. }
  44. }
  45. void PDataManager::UnregisterPdata(RUNTIME_FUNCTION* pdata)
  46. {
  47. if (AutoSystemInfo::Data.IsWin8OrLater())
  48. {
  49. NtdllLibrary::Instance->DeleteGrowableFunctionTable(pdata);
  50. }
  51. else
  52. {
  53. BOOLEAN success = RtlDeleteFunctionTable(pdata);
  54. Assert(success);
  55. }
  56. }
  57. #else // !_WIN32
  58. // ----------------------------------------------------------------------------
  59. // !_WIN32 x64 unwind uses .eh_frame
  60. // ----------------------------------------------------------------------------
  61. void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart,
  62. _In_ const ULONG_PTR functionStart, _In_ const ULONG_PTR functionEnd,
  63. _Out_ PVOID* pdataTable, ULONG entryCount, ULONG maxEntryCount)
  64. {
  65. __REGISTER_FRAME(pdataStart);
  66. *pdataTable = pdataStart;
  67. }
  68. void PDataManager::UnregisterPdata(RUNTIME_FUNCTION* pdata)
  69. {
  70. __DEREGISTER_FRAME(pdata);
  71. }
  72. #endif // !_WIN32
  73. #endif // PDATA_ENABLED