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