extern void DWRScanFileTable( drmem_hdl start, file_info *nametab, file_table *idxtab ) /****************************************************************/ // find the filenames in the line information, and return them in a table { drmem_hdl finish; file_table curridxmap; char *name; int index; filetab_idx ftidx; unsigned length; unsigned_8 *oparray; int op_base; int value; unsigned_32 stmt_offset; dw_lns value_lns; dw_lne value_lne; stmt_offset = (unsigned_32)-1; DWRGetCompileUnitHdr( start, GrabLineAddr, &stmt_offset ); if( stmt_offset == (unsigned_32)-1 ) { return; } start = DWRCurrNode->sections[DR_DEBUG_LINE].base + stmt_offset; finish = start + DWRVMReadDWord( start ); op_base = DWRVMReadByte( start + offsetof( stmt_prologue, opcode_base ) ); start += offsetof( stmt_prologue, standard_opcode_lengths ); oparray = __alloca( op_base - 1 ); for( index = 0; index < op_base - 1; index++ ) { oparray[index] = DWRVMReadByte( start ); start++; } DWRInitFileTable( &curridxmap ); while( start < finish ) { // get directory table value = DWRVMReadByte( start ); if( value == 0 ) { start++; break; } name = DWRVMCopyString( &start ); ftidx = DWRAddFileName( name, &nametab->pathtab ); DWRAddIndex( ftidx, &curridxmap, TAB_IDX_PATH ); } while( start < finish ) { // get filename table value = DWRVMReadByte( start ); if( value == 0 ) { start++; break; } ReadNameEntry( &start, nametab, idxtab, &curridxmap ); } while( start < finish ) { // now go through the statement program value_lns = DWRVMReadByte( start ); start++; if( value_lns == 0 ) { // it's an extended opcode length = DWRVMReadULEB128( &start ); value_lne = DWRVMReadByte( start ); if( value_lne == DW_LNE_define_file ) { start++; ReadNameEntry( &start, nametab, idxtab, &curridxmap ); } else { start += length; } } else if( value_lns < op_base ) { // it is a standard opcode if( value_lns == DW_LNS_fixed_advance_pc ) { start += sizeof( unsigned_16 ); // it is a fixed size } else { // it is a variable # of blocks for( value = oparray[value_lns - 1]; value > 0; --value ) { DWRVMSkipLEB128( &start ); } } } // else it was a special op, and thus only 1 byte long } DWRTrimTableSize( idxtab ); DWRFiniFileTable( &curridxmap, false ); }
static void References( ReferWhich which, dr_handle entry, void *data1, hook_func do_callback, void *data2, DRSYMREF callback ) /*********************************************************************/ { dr_handle loc; dr_handle end; dr_handle owning_node; dr_handle infoOffset; unsigned_8 opcode; dr_ref_info registers = { { 0, 0, NULL }, 0L, NULL, 1L, 1 }; bool quit = FALSE; bool inScope = FALSE; loc = DWRCurrNode->sections[ DR_DEBUG_REF ].base; end = loc + DWRCurrNode->sections[ DR_DEBUG_REF ].size; infoOffset = DWRCurrNode->sections[ DR_DEBUG_INFO ].base; loc += sizeof( unsigned_32 ); /* skip size */ while( loc < end && !quit ) { opcode = DWRVMReadByte( loc ); loc += sizeof( unsigned_8 ); switch( opcode ) { case REF_BEGIN_SCOPE: owning_node = DWRVMReadDWord( loc ) + infoOffset; loc += sizeof( unsigned_32 ); ScopePush( ®isters.scope, owning_node ); if( (which & REFERSTO) != 0 && owning_node == entry ) { inScope = TRUE; } break; case REF_END_SCOPE: ScopePop( ®isters.scope ); inScope = FALSE; break; case REF_SET_FILE: registers.file = DWRFindFileName( DWRVMReadULEB128( &loc ), infoOffset ); break; case REF_SET_LINE: registers.line = DWRVMReadULEB128( &loc ); break; case REF_SET_COLUMN: registers.column = (unsigned_8)DWRVMReadULEB128( &loc ); break; case REF_ADD_LINE: registers.line += DWRVMReadSLEB128( &loc ); registers.column = 0; break; case REF_ADD_COLUMN: registers.column += (signed_8)DWRVMReadSLEB128( &loc ); break; case REF_COPY: default: if( opcode >= REF_CODE_BASE ) { unsigned_32 ld; opcode -= REF_CODE_BASE; ld = opcode / REF_COLUMN_RANGE; if( ld != 0 ) { registers.column = 0; registers.line += ld; } registers.column += opcode % REF_COLUMN_RANGE; registers.dependent = DWRVMReadDWord( loc ) + infoOffset; loc += sizeof( unsigned_32 ); } quit = FALSE; /* don't terminate */ if( do_callback( ®isters, data1 ) || inScope ) { char *name = NULL; owning_node = ScopeLastNameable( ®isters.scope, &name ); /* make sure that there is something nameable on the stack */ if( owning_node != DR_HANDLE_NUL ) { quit = !callback( owning_node, ®isters, name, data2 ); } } break; } } DWRFREE( registers.scope.stack ); }