Example #1
0
void MergeRelocate::addReloc( MergeOffset & off, MergeDIE * replacer )
//--------------------------------------------------------------------
{
//    _replacedDies[ off.fileIdx ]->insert( off.offset, replacer );

    #if ( INSTRUMENTS == INSTRUMENTS_FULL_LOGGING )
        MergeDIE * replaced = getReloc( off );
        Log.printf( "    reloc from %s %s to ",
//                        ((const MergeNameKey&)(*replaced)).getString(),
//                        ((const MergeOffset&)(*replaced)).getString() );
                        ( replaced != NULL ) ? replaced->name().getString() : "NULL",
                        ( replaced != NULL ) ? replaced->offset().getString() : "NULL" );
//        Log.printf( "%s %s\n", ((const MergeNameKey&)(*replacer)).getString(),
//                        ((const MergeOffset&)(*replacer)).getString() );
        Log.printf( "%s %s\n",
                        ( replacer != NULL ) ? replacer->name().getString() : "NULL",
                        ( replacer != NULL ) ? replacer->offset().getString() : "NULL" );
    #endif
    _replacedDies[ off.fileIdx ]->insert( off.offset, replacer );
}
Example #2
0
void MergeInfoSection::relocPass( MergeInfoPP & post )
//----------------------------------------------------
{
    MergeDIE *  die;
    uint_32     offset = 0;

    offset += sizeof( MergeCompunitHdr );

    _diesByName->setToStart();
    die = _diesByName->next();              // set to first
    while( die ) {
        if( !die->assigned() ) {
            die->setNewOff( this, offset, post );
        }
        die = _diesByName->next();
    }

    post.addRequest( MergeOffset( 0, 0 ), offset, 0 );
    _compunitHdr->_infoLength = offset - sizeof(uint_32);
    _compunitHdr->_infoLength += 1;  // for discarded compunit-terminator
}
Example #3
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() );
        }
    }
}
Example #4
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 );
                }
            }
        }
    }
}
Example #5
0
void MergeInfoSection::readDIE( MergeFile * file, MergeOffset startOff,
                                MergeDIE * prt, MergeOffset& moff,
                                uint_32 abbCode )
//-------------------------------------------------------------------
// read a die and all its children, adding to _dies.  return false when
// the abbrev code is zero (recursive)
{
    MergeDIE *      die;                // one we read
    MergeAbbrev *   abbrev;

    MergeOffset     child;              // offset of first child
    MergeOffset     sibling;

    bool            ext = TRUE;         // external or static?
    bool            defn = TRUE;        // is a definition?
    const char *    name = NULL;
    int             i;
    DIELen_T        length;
    int             lenDelta = 0;       // delta from changing file idx

    if( abbCode == 0 ) {
        length = (DIELen_T) (moff.offset - startOff.offset);

        MergeNameKey nmKey( abbCode, ext, NULL, 0 );
        die = new MergeDIE( prt, startOff, nmKey, child, sibling, defn, length );

        die = die->collision( _diesByName );

        #if INSTRUMENTS
        if( abbrev == NULL ) {
            Log.printf( "zoiks! %s\n", startOff.getString() );
        }
        #endif

        return;     //<------------------- early return
    }

    abbrev = _abbrevs.getAbbrev( abbCode );

    #if INSTRUMENTS
    if( abbrev == NULL ) {
        Log.printf( "ABBREV == NULL!  offset is %s, %s\n", startOff.getString(), moff.getString() );
    }
    #endif

    InfoAssert( abbrev != NULL );       // NYI throw

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

        switch( att.attrib() ) {
        case DW_AT_name:
            name = file->readString( DR_DEBUG_INFO, moff.offset );
            if( abbrev->tag() == DW_TAG_compile_unit ) {
                name = MagicCompunitName;
            }
            break;
        case DW_AT_sibling:
            sibling.fileIdx = moff.fileIdx;
            sibling.offset = file->readDWord( DR_DEBUG_INFO, moff.offset );
            break;
        case DW_AT_external:
            ext = file->readByte( DR_DEBUG_INFO, moff.offset );
            break;
        case DW_AT_declaration:
            defn = !file->readByte( DR_DEBUG_INFO, moff.offset );
            break;
        case DW_AT_decl_file:
            lenDelta = getFileLenDelta( file, moff, att.form() );
            break;
        default:
            file->skipForm( DR_DEBUG_INFO, moff.offset, att.form(),
                            getAddrSize() );
        }
    }

    if( abbrev->hasChildren() ) {
        child = moff;
    }

    length = (DIELen_T)(moff.offset - startOff.offset + lenDelta);

    MergeNameKey nmKey( abbrev->tag(), ext, name, 0 );
    die = new MergeDIE( prt, startOff, nmKey, child, sibling, defn, length );
    die = die->collision( _diesByName );
    getReloc().addReloc( startOff, die );

    if( abbrev->hasChildren() ) {
        while( 1 ) {
            startOff = moff;
            abbCode = file->readULEB128( DR_DEBUG_INFO, moff.offset );

            if( abbCode == 0 ) break;

            readDIE( file, startOff, die, moff, abbCode );
        }
    }

    if( !die->siblingSet() ) {
        die->setSibling( moff );
    }
}