//*****************************************************************************
// Pull the PEKind and Machine out of PE headers -- if we have PE headers.
//*****************************************************************************
HRESULT CLiteWeightStgdbRW::GetPEKind(  // S_OK or error.
    MAPPINGTYPE mtMapping,              // The type of mapping the image has
    DWORD       *pdwPEKind,             // [OUT] The kind of PE (0 - not a PE)
    DWORD       *pdwMachine)            // [OUT] Machine as defined in NT header
{
    HRESULT     hr = NOERROR;
    DWORD       dwKind=0;               // Working copy of pe kind.
    DWORD       dwMachine=0;            // Working copy of machine.

#ifndef DACCESS_COMPILE
    // Do we already have cached information?
    if (m_dwPEKind != (DWORD)(-1))
    {
        dwKind = m_dwPEKind;
        dwMachine = m_dwMachine;
    }
    else if (m_pImage)
    {
        NewHolder<PEDecoder> pe;

        EX_TRY
        {
            // We need to use different PEDecoder constructors based on the type of data we give it.
            // We use the one with a 'bool' as the second argument when dealing with a mapped file,
            // and we use the one that takes a COUNT_T as the second argument when dealing with a
            // flat file.

            if (mtMapping == MTYPE_IMAGE)
                pe = new (nothrow) PEDecoder(m_pImage, false);
            else
                pe = new (nothrow) PEDecoder(m_pImage, (COUNT_T)(m_dwImageSize));
        
        }
        EX_CATCH
        {
            hr = COR_E_BADIMAGEFORMAT;
        }
        EX_END_CATCH(SwallowAllExceptions)

        IfFailRet(hr);
        IfNullRet(pe);


        if (pe->HasContents() && pe->HasNTHeaders())
        {
            pe->GetPEKindAndMachine(&dwKind,&dwMachine);
            // Cache entries.
            m_dwPEKind = dwKind;
            m_dwMachine = dwMachine;
        }
        else // if (pe.HasContents()...
            hr = COR_E_BADIMAGEFORMAT;
    } // if (m_pImage)
    else 
Exemple #2
0
// --------------------------------------------------------------------------------------
// 
// Stores hot data reported by IBC in profile data (code:CorProfileData) to a stream.
// Aligns output stream to 4-bytes.
// 
__checkReturn 
HRESULT 
HotHeapWriter::SaveToStream(
    IStream        *pStream, 
    CorProfileData *pProfileData, 
    UINT32         *pnSavedSize) const
{
    _ASSERTE(pStream != NULL);
    _ASSERTE(pProfileData != NULL);
    _ASSERTE(pnSavedSize != NULL);
    
#ifdef FEATURE_PREJIT
    HRESULT hr = S_OK;
    UINT32 nOffset = 0;
    UINT32 nValueHeapStart_PositiveOffset;
    UINT32 nValueOffsetTableStart_PositiveOffset;
    UINT32 nIndexTableStart_PositiveOffset;
    
    // data
    //
    
    // number of hot tokens
    UINT32 nHotItemsCount = pProfileData->GetHotTokens(
        GetTableIndex(), 
        1 << ProfilingFlags_MetaData, 
        1 << ProfilingFlags_MetaData, 
        NULL, 
        0);
    CONSISTENCY_CHECK(nHotItemsCount != 0);
    
    NewArrayHolder<UINT32> hotItemArr = new (nothrow) UINT32[nHotItemsCount];
    IfNullRet(hotItemArr);
    
    // get hot tokens
    static_assert_no_msg(sizeof(UINT32) == sizeof(mdToken));
    pProfileData->GetHotTokens(
        GetTableIndex(), 
        1 << ProfilingFlags_MetaData, 
        1 << ProfilingFlags_MetaData, 
        reinterpret_cast<mdToken *>(&hotItemArr[0]), 
        nHotItemsCount);
    
    // convert tokens to rids
    for (UINT32 i = 0; i < nHotItemsCount; i++)
    {
        hotItemArr[i] = RidFromToken(hotItemArr[i]);
    }
    
    NewArrayHolder<RidOffsetPair> offsetMapping = new (nothrow) RidOffsetPair[nHotItemsCount];
    IfNullRet(offsetMapping);
    
    // write data
    nValueHeapStart_PositiveOffset = nOffset;
    
    // note that we write hot items in the order they appear in pProfileData->GetHotTokens
    // this is so that we preserve the ordering optimizations done by IbcMerge
    for (UINT32 i = 0; i < nHotItemsCount; i++)
    {
        DataBlob data;
        IfFailRet(GetData(
            hotItemArr[i], 
            &data));
        
        // keep track of the offset at which each hot item is written
        offsetMapping[i].rid = hotItemArr[i];
        offsetMapping[i].offset = nOffset;
        
        IfFailRet(StreamUtil::WriteToStream(
            pStream, 
            data.GetDataPointer(), 
            data.GetSize(), 
            &nOffset));
    }
    
    IfFailRet(StreamUtil::AlignDWORD(pStream, &nOffset));
    
    // sort by rid so that a hot rid can be looked up by binary search
    qsort(offsetMapping, nHotItemsCount, sizeof(RidOffsetPair), RidOffsetPair::Compare);
    
    // initialize table of offsets to data
    NewArrayHolder<UINT32> dataIndices = new (nothrow) UINT32[nHotItemsCount];
    IfNullRet(dataIndices);
    
    // fill in the hotItemArr (now sorted by rid) and dataIndices array with each offset
    for (UINT32 i = 0; i < nHotItemsCount; i++)
    {
        hotItemArr[i] = offsetMapping[i].rid;
        dataIndices[i] = offsetMapping[i].offset;
    }
    
    // table of offsets to data
    //
    
    nValueOffsetTableStart_PositiveOffset = nOffset;
    IfFailRet(StreamUtil::WriteToStream(pStream, &dataIndices[0], sizeof(UINT32) * nHotItemsCount, &nOffset));
    
    // rid table (sorted)
    //
    
    nIndexTableStart_PositiveOffset = nOffset;
    
    IfFailRet(StreamUtil::WriteToStream(pStream, &hotItemArr[0], nHotItemsCount * sizeof(UINT32), &nOffset));
    IfFailRet(StreamUtil::AlignDWORD(pStream, &nOffset));
    
    {
        // hot pool header
        struct HotHeapHeader header;
        
        // fix offsets
        header.m_nIndexTableStart_NegativeOffset = nOffset - nIndexTableStart_PositiveOffset;
        header.m_nValueOffsetTableStart_NegativeOffset = nOffset - nValueOffsetTableStart_PositiveOffset;
        header.m_nValueHeapStart_NegativeOffset = nOffset - nValueHeapStart_PositiveOffset;
        
        // write header
        IfFailRet(StreamUtil::WriteToStream(pStream, &header, sizeof(header), &nOffset));
    }
    
    *pnSavedSize = nOffset;
    
#endif //FEATURE_PREJIT
    
    return S_OK;
} // HotHeapWriter::PersistHotToStream