mrline.cpp

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 415 行 · 第 1/2 页

CPP
415
字号


    total_length =      file->readDWord( DR_DEBUG_LINE, moff.offset );
    version =           file->readWord( DR_DEBUG_LINE, moff.offset );
    prologue_length =   file->readDWord( DR_DEBUG_LINE, moff.offset );

    lineEnd = startOff.offset + sizeof(uint_32) + total_length;

    // skip minimum_instruction_length, default_is_stmt, line_base, line_range
    moff.offset += 1 + 1 + 1 + 1;

    op_base = file->readByte( DR_DEBUG_LINE, moff.offset );
    standard_opcode_lengths = new uint_8[ op_base ];

    for( i = 0; i < op_base - 1; i += 1 ) {
        standard_opcode_lengths[ i ] = file->readByte( DR_DEBUG_LINE,
                                                        moff.offset );
    }

    // directory indicies start at 1
    for( i = 1; moff.offset < lineEnd; i += 1 ) {
        string = file->readString( DR_DEBUG_LINE, moff.offset );

        if( string == NULL ) break;     // <------- end of directories
        name = string;

        addDirectory( moff.fileIdx, i, name );
    }

    for( i = 1; moff.offset < lineEnd; i += 1 ) {
        if( !readFileEntry( file, moff, i ) ) break;  // <----- end of files
    }

    while( moff.offset < lineEnd ) {
        opcode = file->readByte( DR_DEBUG_LINE, moff.offset );
        if( opcode == 0 ) {     // extended opcode
            oplen =     file->readULEB128( DR_DEBUG_LINE, moff.offset );
            extopcode = file->readULEB128( DR_DEBUG_LINE, moff.offset );

            if( extopcode == DW_LNE_define_file ) {
                readFileEntry( file, moff, i );
                i += 1;
            } else {
                moff.offset += oplen;   // skip unwanted extended opcode
            }
        } else {
            if( opcode < op_base ) {
                if( opcode == DW_LNS_fixed_advance_pc ) {
                    moff.offset += sizeof(unsigned_16); // it's a fixed size
                } else {                            // it's variable # of leb's
                    oplen = standard_opcode_lengths[opcode];
                    while( oplen > 0 ) {
                        file->readULEB128( DR_DEBUG_LINE, moff.offset ); // skip
                        oplen--;
                    }
                }
            } else {
                // it was a special opcode, only one byte long, so we
                // already skipped it
            }
        }
    }

    delete standard_opcode_lengths;
}

void MergeLineSection::addDirectory( uint_8 fileIdx, uint_16 oldDirIdx,
                                     MergeStringHdl & dir )
//---------------------------------------------------------------------
{
    uint_16 newDirIdx;
    MergeFileRelocKey relKey( fileIdx, oldDirIdx );

    // NYI -- if oldDirIdx == 0, then it means in the current compile
    // directory, but that will possibly be different accross compunits.

    InternalAssert( oldDirIdx != 0 );       // NYI throw

    if( _directoriesByName->contains( dir ) ) {
        newDirIdx = (*_directoriesByName)[ dir ];
    } else {
        newDirIdx = (uint_16)( _directories->entries() + 1 );
        _directories->append( dir );
        (*_directoriesByName)[ dir ] = newDirIdx;
    }
    (*_directoriesReloc)[ relKey ] = newDirIdx;
}

bool MergeLineSection::readFileEntry( MergeFile * file, MergeOffset & moff,
                                        uint_16 oldFileIdx )
//-------------------------------------------------------------------------
{
    const char *    string;
    MergeFileEntry  fileEntry;

    string = file->readString( DR_DEBUG_LINE, moff.offset );

    if( string == NULL ) return FALSE;  // end of files

    fileEntry.name.operator=( string );
    fileEntry.directoryIdx = (uint_16)  file->readULEB128( DR_DEBUG_LINE, moff.offset );
    fileEntry.modTime =         file->readULEB128( DR_DEBUG_LINE, moff.offset );
    fileEntry.length =          file->readULEB128( DR_DEBUG_LINE, moff.offset );

    addFile( moff.fileIdx, oldFileIdx, fileEntry );

    return TRUE;
}

void MergeLineSection::addFile( uint_8 fileIdx, uint_16 oldFileIdx,
                                MergeFileEntry& file )
//-----------------------------------------------------------------
{
    uint_16  newFileIdx;
    MergeFileRelocKey reloc( fileIdx, oldFileIdx );

    if( _filesByName->contains( file.name ) ) {
        newFileIdx = (*_filesByName)[ file.name ];
    } else {
        newFileIdx = (uint_16)( _files->entries() + 1 );

        if( file.directoryIdx != 0 ) {
            MergeFileRelocKey reloc( fileIdx, file.directoryIdx );
            file.directoryIdx = (*_directoriesReloc)[ reloc ];
        }
        _files->append( file );
        (*_filesByName)[ file.name ] = newFileIdx;
    }
    (*_filesReloc)[ reloc ] = newFileIdx;
}

uint_16 MergeLineSection::getNewFileIdx( uint_8 mbrFile, uint_16 oldIdx )
//-----------------------------------------------------------------------
{
    MergeFileRelocKey key( mbrFile, oldIdx );

    #if INSTRUMENTS
    if( !_filesReloc->contains( key ) ) {
        Log.printf( "Could not find a relocation record for <%d,%d>\n", mbrFile, oldIdx );
        Log.printf( "_fileReloc:\n" );
        WCValHashDictIter<MergeFileRelocKey,uint_16> iter( *_filesReloc );

        while( iter.operator++() ) {
            Log.printf( "<%hu,%u|%u>\n", iter.key().mbrFile, iter.key().oldIdx, iter.value() );
        }
        Log.printf( "_files:\n" );
        for( int i = 0; i < _files->entries(); i += 1 ) {
            Log.printf( "<%d|%s,%d>\n", i, (*_files)[i].name.getString(), (*_files)[i].directoryIdx );
        }
    }
    #endif

    InfoAssert( _filesReloc->contains( key ) );
    return (*_filesReloc)[ key ];
}

void MergeLineSection::writePass( MergeFile * outFile )
//-----------------------------------------------------
{
    uint_32 length;
    int     i;

    // total_length, version, prologue_length
    length = sizeof(uint_32) + sizeof(uint_16) + sizeof(uint_32);

    // minimum_instruction_length, default_is_stmt, line_base, line_range
    length += sizeof(uint_8) + sizeof(uint_8) + sizeof(int_8) + sizeof(uint_8);

    // opcode_base, standard_opcode_lengths
    length += sizeof(uint_8) + 0;

    // directories
    for( i = 0; i < _directories->entries(); i += 1 ) {
        length += strlen( (*_directories)[ i ].getString() ) + 1;
    }
    length += sizeof( uint_8 );     // terminating null for directories

    // files
    for( i = 0; i < _files->entries(); i += 1 ) {
        length += (*_files)[ i ].getLen();
    }
    length += sizeof( uint_8 );     // terminating null for directories

    outFile->writeDWord( length - sizeof(uint_32) );
    outFile->writeWord( 2 );
    outFile->writeDWord( length - 4 - 2 - 4 );          // subtract header

    outFile->writeByte( 0 );        // miminum_instruction_length
    outFile->writeByte( 0 );        // default_is_stmt
    outFile->writeByte( 0 );        // line_base
    outFile->writeByte( 0 );        // line_range
    outFile->writeByte( 1 );        // opcode_base

    for( i = 0; i < _directories->entries(); i += 1 ) {
        outFile->writeString( (*_directories)[ i ].getString() );
    }
    outFile->writeByte( 0 );    // terminate paths

    for( i = 0; i < _files->entries(); i += 1 ) {
        outFile->writeString( (*_files)[ i ].name.getString() );
        outFile->writeULEB128( (*_files)[ i ].directoryIdx );
        outFile->writeULEB128( (*_files)[ i ].modTime );
        outFile->writeULEB128( (*_files)[ i ].length );
    }
    outFile->writeByte( 0 );    // terminate files
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?