<commit_before>/*
   Copyright (c) 2010 <NAME>

   Licensed under the Apache License, Version 2.0.
   See the LICENSE text file for details.
*/

#include "Common.h"
#include "DebugStore.h"
#include "OMFHashTable.h"
#include "OMFAddrTable.h"
#include "SymbolInfo.h"
#include "TypeInfo.h"
#include "Util.h"
#include "cvinfo.h"

using namespace std;

typedef pair<DWORD, DWORD> OffsetPair;


namespace MagoST
{
    DebugStore::DebugStore()
        :   mInit( false ),
            mCVBuf( NULL ),
            mCVBufSize( 0 ),
            mDirHeader( NULL ),
            mDirs( NULL ),
            mGlobalTypesDir( NULL ),
            mCompilandCount( 0 ),
            mTLSSegment( 0 ),
            mTextSegment( 2 )
    {
        memset( mSymsDir, 0, sizeof mSymsDir );

        C_ASSERT( sizeof( SymbolScopeIn ) == sizeof( SymbolScope ) );
        C_ASSERT( sizeof( TypeScopeIn ) == sizeof( TypeScope ) );
        C_ASSERT( sizeof( EnumNamedSymbolsDataIn ) == sizeof( EnumNamedSymbolsData ) );
        C_ASSERT( sizeof( TypeHandleIn ) == sizeof( TypeHandle ) );
        C_ASSERT( sizeof( SymHandleIn ) == sizeof( SymHandle ) );
    }

    DebugStore::~DebugStore()
    {
    }

    HRESULT DebugStore::SetCVBuffer( BYTE* buffer, DWORD size )
    {
        if ( (buffer == NULL) || (size == 0) )
            return E_INVALIDARG;
        if ( (buffer + size) < buffer )             // can't wrap around
            return E_INVALIDARG;
        if ( (buffer + size + 0xFFFF) < buffer )    // we compare a lot with sym lengths which are 16-bit
            return E_INVALIDARG;
        if ( mInit )
            return E_ALREADY_INIT;

        mCVBuf = buffer;
        mCVBufSize = size;

        return S_OK;
    }

    HRESULT DebugStore::InitDebugInfo( BYTE* buffer, DWORD size )
    {
        HRESULT hr = S_OK;

        hr = SetCVBuffer( buffer, size );
        if ( FAILED( hr ) )
            return hr;

        hr = InitDebugInfo();
        if ( FAILED( hr ) )
            return hr;

        return S_OK;
    }

    HRESULT DebugStore::InitDebugInfo()
    {
        if ( (mCVBuf == NULL) || (mCVBufSize == 0) )
            return E_INVALIDARG;
        if ( mInit )
            return E_ALREADY_INIT;
        mInit = true;

        HRESULT         hr = S_OK;
        OMFSignature*   sig = GetCVPtr<OMFSignature>( 0 );
        OMFDirHeader*   dirHeader = NULL;

        if ( sig == NULL )
            return E_BAD_FORMAT;

        if ( memcmp( sig->Signature, "NB09", 4 ) != 0 )
            return E_BAD_FORMAT;

        dirHeader = GetCVPtr<OMFDirHeader>( sig->filepos );
        if ( dirHeader == NULL )
            return E_BAD_FORMAT;

        BYTE* dirStart = GetCVPtr<BYTE>( sig->filepos + dirHeader->cbDirHeader, dirHeader->cDir * dirHeader->cbDirEntry);
        BYTE* dir = dirStart;

        if ( dir == NULL )
            return E_BAD_FORMAT;

        for ( DWORD i = 0; i < dirHeader->cDir; i++ )
        {
            OMFDirEntry*    entry = (OMFDirEntry*) dir;

            hr = ProcessDirEntry( entry );
            if ( FAILED( hr ) )
                return hr;

            dir += dirHeader->cbDirEntry;
        }

        mDirHeader = (OMFDirHeader*) dirHeader;
        mDirs = (OMFDirEntry*) dirStart;

        return S_OK;
    }

    void DebugStore::SetTLSSegment( WORD seg )
    {
        mTLSSegment = seg;
    }

    void DebugStore::SetTextSegment( WORD seg )
    {
        mTextSegment = seg;
    }

    HRESULT DebugStore::ProcessDirEntry( OMFDirEntry* entry )
    {
        _ASSERT( entry != NULL );

        if ( NULL == GetCVPtr<void>( entry->lfo, entry->cb ) )
            return E_BAD_FORMAT;

        switch ( entry->SubSection )
        {
        case sstModule:
            _ASSERT( mCompilandDetails.get() == NULL );
            if ( mCompilandDetails.get() == NULL )
                mCompilandCount++;
            // else, ignore all the ones after this stage, because they shouldn't be here
            
            MarkLineNumbers( entry );
            break;

        case sstAlignSym:
        case sstSrcModule:
            if ( mCompilandDetails.get() == NULL )
            {
                mCompilandDetails.reset( new CompilandDetails[ mCompilandCount ] );
                if ( mCompilandDetails.get() == NULL )
                    return E_OUTOFMEMORY;
                memset( mCompilandDetails.get(), 0, mCompilandCount * sizeof( CompilandDetails ) );
            }

            if ( (entry->iMod == 0) || (entry->iMod > mCompilandCount) )
                return E_BAD_FORMAT;
<commit_msg>fix for optlink bug: ignore bad dir entries produced by optlink<commit_after>/*
   Copyright (c) 2010 <NAME>

   Licensed under the Apache License, Version 2.0.
   See the LICENSE text file for details.
*/

#include "Common.h"
#include "DebugStore.h"
#include "OMFHashTable.h"
#include "OMFAddrTable.h"
#include "SymbolInfo.h"
#include "TypeInfo.h"
#include "Util.h"
#include "cvinfo.h"

using namespace std;

typedef pair<DWORD, DWORD> OffsetPair;


namespace MagoST
{
    DebugStore::DebugStore()
        :   mInit( false ),
            mCVBuf( NULL ),
            mCVBufSize( 0 ),
            mDirHeader( NULL ),
            mDirs( NULL ),
            mGlobalTypesDir( NULL ),
            mCompilandCount( 0 ),
            mTLSSegment( 0 ),
            mTextSegment( 2 )
    {
        memset( mSymsDir, 0, sizeof mSymsDir );

        C_ASSERT( sizeof( SymbolScopeIn ) == sizeof( SymbolScope ) );
        C_ASSERT( sizeof( TypeScopeIn ) == sizeof( TypeScope ) );
        C_ASSERT( sizeof( EnumNamedSymbolsDataIn ) == sizeof( EnumNamedSymbolsData ) );
        C_ASSERT( sizeof( TypeHandleIn ) == sizeof( TypeHandle ) );
        C_ASSERT( sizeof( SymHandleIn ) == sizeof( SymHandle ) );
    }

    DebugStore::~DebugStore()
    {
    }

    HRESULT DebugStore::SetCVBuffer( BYTE* buffer, DWORD size )
    {
        if ( (buffer == NULL) || (size == 0) )
            return E_INVALIDARG;
        if ( (buffer + size) < buffer )             // can't wrap around
            return E_INVALIDARG;
        if ( (buffer + size + 0xFFFF) < buffer )    // we compare a lot with sym lengths which are 16-bit
            return E_INVALIDARG;
        if ( mInit )
            return E_ALREADY_INIT;

        mCVBuf = buffer;
        mCVBufSize = size;

        return S_OK;
    }

    HRESULT DebugStore::InitDebugInfo( BYTE* buffer, DWORD size )
    {
        HRESULT hr = S_OK;

        hr = SetCVBuffer( buffer, size );
        if ( FAILED( hr ) )
            return hr;

        hr = InitDebugInfo();
        if ( FAILED( hr ) )
            return hr;

        return S_OK;
    }

    HRESULT DebugStore::InitDebugInfo()
    {
        if ( (mCVBuf == NULL) || (mCVBufSize == 0) )
            return E_INVALIDARG;
        if ( mInit )
            return E_ALREADY_INIT;
        mInit = true;

        HRESULT         hr = S_OK;
        OMFSignature*   sig = GetCVPtr<OMFSignature>( 0 );
        OMFDirHeader*   dirHeader = NULL;

        if ( sig == NULL )
            return E_BAD_FORMAT;

        if ( memcmp( sig->Signature, "NB09", 4 ) != 0 )
            return E_BAD_FORMAT;

        dirHeader = GetCVPtr<OMFDirHeader>( sig->filepos );
        if ( dirHeader == NULL )
            return E_BAD_FORMAT;

        BYTE* dirStart = GetCVPtr<BYTE>( sig->filepos + dirHeader->cbDirHeader, dirHeader->cDir * dirHeader->cbDirEntry);
        BYTE* dir = dirStart;

        if ( dir == NULL )
            return E_BAD_FORMAT;

        for ( DWORD i = 0; i < dirHeader->cDir; i++ )
        {
            OMFDirEntry*    entry = (OMFDirEntry*) dir;

            hr = ProcessDirEntry( entry );
            if ( FAILED( hr ) )
                return hr;

            dir += dirHeader->cbDirEntry;
        }

        mDirHeader = (OMFDirHeader*) dirHeader;
        mDirs = (OMFDirEntry*) dirStart;

        return S_OK;
    }

    void DebugStore::SetTLSSegment( WORD seg )
    {
        mTLSSegment = seg;
    }

    void DebugStore::SetTextSegment( WORD seg )
    {
        mTextSegment = seg;
    }

    HRESULT DebugStore::ProcessDirEntry( OMFDirEntry* entry )
    {
        _ASSERT( entry != NULL );

        if ( NULL == GetCVPtr<void>( entry->lfo, entry->cb ) )
            return S_OK; // was E_BAD_FORMAT; optlink produces some bad records, so ignore them

        switch ( entry->SubSection )
        {
        case sstModule:
            _ASSERT( mCompilandDetails.get() == NULL );
            if ( mCompilandDetails.get() == NULL )
                mCompilandCount++;
            // else, ignore all the ones after this stage, because they shouldn't be here
            
            MarkLineNumbers( entry );
            break;

        case sstAlignSym:
        case sstSrcModule:
            if ( mCompilandDetails.get() == NULL )
            {
                mCompilandDetails.reset( new CompilandDetails[ mCompilandCount ] );
                if ( mCompilandDetails.get() == NULL )
                    return E_OUTOFMEMORY;
                memset( mCompilandDetails.get(), 0, mCompilandCount * sizeof( CompilandDetails ) );
            }

            if ( (entry->iMod == 0) || (entry->iMod > mCompilandCount) )
                return E_BAD_FORMAT;

{'fraction_non_alphanumeric': 0.10622072121146095, 'fraction_numerical': 0.005229327813487308, 'mean_word_length': 1.7885783718104495, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4007653', 'n_tokens_mistral': 2896, 'n_tokens_neox': 2755, 'n_words': 704}