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() ); } } }
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 ); } } } } }