Пример #1
0
void MergeRefSection::scanFile( MergeFile * file, uint_8 indx,
                                RefLineCol & absLnCol )
//------------------------------------------------------------
{
    uint_32     unitLength;     // length of ref info for this compunit
    uint_32     user;           // referencing die
    uint_32     dependant;      // referenced die
    uint_32     fileIdx;        // containing file
    int_32      linecoldelta;   // line / column delta
    uint_32     linecol;        // absolute line / column
    uint_8      opcode;         // state-machine op-code
    uint_32     offset = 0;     // offset into the ref-section for this file
    MergeDIE *  die;            // the user / dependent die
    RefLineCol  currLnCol;      // registers if this is the only file
    bool        replaced;       // true if the scope is dead
    MergeOffset keyOff(indx,0); // key to search in reloc table

    unitLength = file->readDWord( DR_DEBUG_REF, offset );

    while( offset < unitLength + sizeof(uint_32) ) {
        opcode = file->readByte( DR_DEBUG_REF, offset );

        switch( opcode ) {
        case REF_BEGIN_SCOPE:
            user = file->readDWord( DR_DEBUG_REF, offset );

            keyOff.offset = user;
            die = _info.getReloc().getReloc( keyOff );

            #if INSTRUMENTS
            if( die == NULL ) {
                Log.printf( "Could not find user DIE <Target: %hd, source: %#lx>!\n", indx, user );
            }
            #endif

            InfoAssert( die != NULL );

            replaced = (die->offset().offset != keyOff.offset);

            if( replaced ) {
                skipDeadScope( file, offset, unitLength + sizeof(uint_32),
                                currLnCol );
            } else {
                _outFile->writeByte( opcode );
                _outFile->writeDWord( die->getNewOff() );
            }
            break;

        case REF_SET_FILE:
            _outFile->writeByte( opcode );
            fileIdx = file->readULEB128( DR_DEBUG_REF, offset );
            fileIdx = _line.getNewFileIdx( indx, fileIdx );
            _outFile->writeULEB128( fileIdx );
            break;

        case REF_SET_LINE:
            _outFile->writeByte( opcode );
            linecol = file->readULEB128( DR_DEBUG_REF, offset );
            _outFile->writeULEB128( linecol );

            absLnCol.setLine( linecol );
            currLnCol.setLine( linecol );
            break;

        case REF_SET_COLUMN:
            _outFile->writeByte( opcode );
            linecol = file->readULEB128( DR_DEBUG_REF, offset );
            _outFile->writeULEB128( linecol );

            absLnCol.setColumn( linecol );
            currLnCol.setColumn( linecol );
            break;

        case REF_ADD_LINE:
            _outFile->writeByte( opcode );
            linecoldelta = file->readSLEB128( DR_DEBUG_REF, offset );
            currLnCol.addLine( linecoldelta );
            linecoldelta = currLnCol.line - absLnCol.line;
            absLnCol.addLine( linecoldelta );
            _outFile->writeSLEB128( linecoldelta );
            break;

        case REF_ADD_COLUMN:
            _outFile->writeByte( opcode );
            linecoldelta = file->readSLEB128( DR_DEBUG_REF, offset );
            currLnCol.addColumn( linecoldelta );
            linecoldelta = currLnCol.col - absLnCol.col;
            absLnCol.addColumn( linecoldelta );
            _outFile->writeSLEB128( linecoldelta );
            break;

        case REF_COPY:
        case REF_END_SCOPE:
            _outFile->writeByte( opcode );
            break;

        case REF_CODE_BASE:
        default:
            /* special opcode */

            dependant = file->readDWord( DR_DEBUG_REF, offset );

            keyOff.offset = dependant;

            die = _info.getReloc().getReloc( keyOff );

#if 0
            if( die == NULL ) {
                die = _info.find( MergeOffset( indx, dependant ) );
            }
#endif

            #if INSTRUMENTS
            if( die == NULL ) {
                Log.printf( "Could not find dependant die <Target: %hd, dependent: %#lx>!\n", indx, dependant );
                Log.printf( "   user == <Target: %hd, source: %#lx>!", indx, user );

                MergeDIE *  usedie;
                usedie = _info.getReloc().getReloc( MergeOffset( indx, user ) );
#if 0
                if( !usedie ) {
                    usedie = _info.find( MergeOffset( indx, user ) );
                }
#endif
                if( usedie ) {
                    Log.printf( " %s\n", (const char *)(*usedie) );
                } else {
                    Log.printf( "\n" );
                }

                fprintf( stderr, "Could not find dependant die!\n" );
                continue;
            }
            #endif

            InfoAssert( die != NULL );

            currLnCol.codeBase( opcode );
            if( currLnCol.line < absLnCol.line
                || (currLnCol.line - absLnCol.line) >
                    (255 - REF_CODE_BASE) / REF_COLUMN_RANGE ) {

                absLnCol.setLine( currLnCol.line );
                _outFile->writeByte( REF_SET_LINE );
                _outFile->writeULEB128( currLnCol.line );
            }

            if( currLnCol.line == absLnCol.line ) {
                if( (currLnCol.col < absLnCol.col)
                    || (currLnCol.col - absLnCol.col) >= REF_COLUMN_RANGE ) {
                    absLnCol.setColumn( currLnCol.col );
                    _outFile->writeByte( REF_SET_COLUMN );
                    _outFile->writeULEB128( currLnCol.col );
                }
            } else {
                if( (currLnCol.col) >= REF_COLUMN_RANGE ) {
                    absLnCol.setColumn( currLnCol.col );
                    _outFile->writeByte( REF_SET_COLUMN );
                    _outFile->writeULEB128( currLnCol.col );
                }
            }

            opcode = absLnCol.makeCodeBase( currLnCol.line, currLnCol.col );
            _outFile->writeByte( opcode );
            _outFile->writeDWord( die->getNewOff() );
        }
    }
}
Пример #2
0
void MergeInfoPP::doFile( MergeInfoSection * sect,
                          MergeFile & outFile,
                          MergeFile & inFile,
                          uint fileIdx,
                          InfoPPReqNode ** reqs,
                          uint numReqs )
//------------------------------------------------------------------
{
    MergeAbbrevSection &    abbrevs( sect->getAbbrev() );
    MergeLineSection &      line( sect->getLine() );
    MergeAbbrev *   abbrev;
    uint_32         abbcode;
    uint_32         offset;
    uint            attribIdx;
    uint            index;
    uint_8          addrSize;
    uint_8          relFile;
    InfoPPReqNode * node;
    MergeOffset     ref( (uint_8) fileIdx, 0 );
    MergeRelocate & reloc( sect->getReloc() );
    MergeDIE *      referredTo;

    addrSize = sect->getAddrSize();

    for( index = 0; index < numReqs; index += 1 ) {
        node = reqs[ index ];
        offset = node->inOff;
        outFile.seekSect( DR_DEBUG_INFO, node->outOff );

        if( offset == 0 ) {
            outFile.writeULEB128( 0 );
            continue;                       // <----------- unusual flow
        }

        abbcode = inFile.readULEB128( DR_DEBUG_INFO, offset );
        if( abbcode == 0 ) {
            outFile.writeULEB128( 0 );
            continue;                       // <----------- unusual flow
        }

        abbrev = abbrevs.getAbbrev( abbcode );
        outFile.writeULEB128( abbcode );

        for( attribIdx = 0; attribIdx < abbrev->entries(); attribIdx += 1 ) {
            MergeAttrib & att( (*abbrev)[ attribIdx ] );

            switch( att.attrib() ) {
            case DW_AT_sibling:
                inFile.skipForm( DR_DEBUG_INFO, offset, att.form(), addrSize );
                outFile.writeForm( att.form(), node->sibOff, addrSize );
                break;
            case DW_AT_decl_file:
                relFile = (uint_8) inFile.readForm( DR_DEBUG_INFO, offset,
                                                 att.form(), addrSize );
                outFile.writeForm( att.form(),
                                    line.getNewFileIdx( (uint_8) fileIdx, relFile ),
                                    addrSize );
                break;
            case DW_AT_macro_info:                  // NYI
            case DW_AT_WATCOM_references_start:     // NYI
                inFile.copyFormTo( outFile, DR_DEBUG_INFO, offset,
                                    att.form(), addrSize );
                break;
            default:
                switch( att.form() ) {
                case DW_FORM_ref4:
                case DW_FORM_ref2:
                case DW_FORM_ref1:
                case DW_FORM_ref_addr:
                case DW_FORM_ref_udata:
                    ref.offset = inFile.readForm( DR_DEBUG_INFO, offset,
                                                att.form(), addrSize );
                    if( ref.offset == 0 ) {
                        outFile.writeForm( att.form(), 0, addrSize );
                    } else {
                        referredTo = reloc.getReloc( ref );

                        #if INSTRUMENTS
                            if( referredTo == NULL ) {
                                Log.printf( "Ack -- can't find a replacement" );
                                Log.printf( " for %#x %s!\n", att.attrib(), ref.getString() );
                            }
                        #endif

                        outFile.writeForm( att.form(), referredTo->getNewOff(),
                                            addrSize );
                    }
                    break;
                case DW_FORM_ref8: /* can't handle 8-byte references */
                default:
                    inFile.copyFormTo( outFile, DR_DEBUG_INFO, offset,
                                        att.form(), addrSize );
                }
            }
        }
    }
}