Example #1
0
void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart,
    _In_ const ULONG_PTR functionStart, _In_ const ULONG_PTR functionEnd,
    _Out_ PVOID* pdataTable, ULONG entryCount, ULONG maxEntryCount)
{
    __REGISTER_FRAME(pdataStart);
    *pdataTable = pdataStart;
}
/* static */
void XDataAllocator::Register(XDataAllocation * xdataInfo, ULONG_PTR functionStart, DWORD functionSize)
{
#ifdef _WIN32
    ULONG_PTR baseAddress = functionStart;
    xdataInfo->pdata.BeginAddress = (DWORD)(functionStart - baseAddress);
    xdataInfo->pdata.UnwindData = (DWORD)((intptr_t)xdataInfo->address - baseAddress);

    NTSTATUS status = NtdllLibrary::Instance->AddGrowableFunctionTable(&xdataInfo->functionTable,
        &xdataInfo->pdata,
        /*MaxEntryCount*/ 1,
        /*Valid entry count*/ 1,
        /*RangeBase*/ functionStart,
        /*RangeEnd*/ functionStart + functionSize);
    BOOLEAN success = NT_SUCCESS(status);
    Assert(!success || xdataInfo->functionTable != nullptr);

    if (!success)
    {
        Js::Throw::XDataRegistrationError(status, functionStart);
    }

#if DBG
    // Validate that the PDATA registration succeeded
    ULONG64            imageBase = 0;
    RUNTIME_FUNCTION  *runtimeFunction = RtlLookupFunctionEntry((DWORD64)functionStart, &imageBase, nullptr);
    Assert(runtimeFunction != NULL);
#endif

#else  // !_WIN32
    Assert(ReadHead(xdataInfo->address));  // should be non-empty .eh_frame
    __REGISTER_FRAME(xdataInfo->address);
#endif
}