cvcue.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 458 行 · 第 1/2 页
C
458 行
ic->pair = lp->cPair - 1;
}
}
dip_status DIPENTRY DIPImpCueAdjust( imp_image_handle *ii,
imp_cue_handle *ic, int adj, imp_cue_handle *aic )
{
cv_directory_entry *cde;
dip_status status;
dip_status ok;
cde = FindDirEntry( ii, ic->im, sstSrcModule );
if( cde == NULL ) {
DCStatus( DS_ERR|DS_INFO_INVALID );
return( DS_ERR|DS_INFO_INVALID );
}
*aic = *ic;
ok = DS_OK;
while( adj > 0 ) {
status = AdjForward( ii, cde->lfo, aic );
if( status & DS_ERR ) return( status );
if( status != DS_OK ) ok = status;
--adj;
}
while( adj < 0 ) {
status = AdjBackward( ii, cde->lfo, aic );
if( status & DS_ERR ) return( status );
if( status != DS_OK ) ok = status;
++adj;
}
return( ok );
}
search_result DIPENTRY DIPImpLineCue( imp_image_handle *ii,
imp_mod_handle im, cue_file_id file, unsigned long line,
unsigned column, imp_cue_handle *ic )
{
cv_directory_entry *cde;
cv_sst_src_module_header *hdr;
cv_sst_src_module_file_table *fp;
cv_sst_src_module_line_number *lp;
unsigned_32 *line_off;
unsigned num_segs;
unsigned seg_idx;
unsigned long best_line;
virt_mem line_base;
virt_mem num_base;
unsigned num_pairs;
unsigned pair;
unsigned_16 *line_number;
column = column;
cde = FindDirEntry( ii, im, sstSrcModule );
if( cde == NULL ) return( SR_NONE );
if( file == 0 ) {
hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) );
if( hdr == NULL ) return( SR_NONE );
file = hdr->baseSrcFile[0] + cde->lfo;
}
ic->im = im;
ic->file = file;
fp = VMBlock( ii, file, sizeof( *fp ) );
if( fp == NULL ) return( SR_NONE );
num_segs = fp->cSeg;
fp = VMBlock( ii, file, sizeof( *fp ) + num_segs * sizeof( unsigned_32 ) );
if( fp == NULL ) return( SR_NONE );
/* make a copy of the line/offset table so that we don't have to worry
about the VM system throwing it out */
line_off = __alloca( num_segs * sizeof( unsigned_32 ) );
memcpy( line_off, &fp->baseSrcLn[0], num_segs * sizeof( unsigned_32 ) );
best_line = -1UL;
for( seg_idx = 0; seg_idx < num_segs; ++seg_idx ) {
line_base = line_off[seg_idx] + cde->lfo;
lp = VMBlock( ii, line_base, sizeof( *lp ) );
if( lp == NULL ) return( SR_NONE );
num_pairs = lp->cPair;
num_base = line_base
+ offsetof( cv_sst_src_module_line_number, offset )
+ (unsigned long)num_pairs * sizeof( unsigned_32 );
for( pair = 0; pair < num_pairs; ++pair ) {
line_number = VMBlock( ii, num_base, sizeof( *line_number ) );
if( *line_number >= line && *line_number < best_line ) {
best_line = *line_number;
ic->line = line_base;
ic->pair = pair;
if( best_line == line ) return( SR_EXACT );
}
num_base += sizeof( *line_number );
}
}
if( best_line == -1UL ) return( SR_NONE );
return( SR_CLOSEST );
}
#define NO_IDX ((unsigned)-1)
unsigned SearchOffsets( imp_image_handle *ii, virt_mem base,
unsigned num_off,
addr_off want_off,
addr_off *best_off,
addr_off adj_off )
{
int lo_idx;
int hi_idx;
int idx;
addr_off lo_off;
addr_off hi_off;
addr_off off;
addr_off *offp;
#define VMADDR( i ) (base + (i)*sizeof(addr_off))
lo_idx = 0;
hi_idx = num_off - 1;
offp = VMBlock( ii, VMADDR( lo_idx ), sizeof( *offp ) );
if( offp == NULL ) return( NO_IDX );
lo_off = *offp + adj_off;
offp = VMBlock( ii, VMADDR( hi_idx ), sizeof( *offp ) );
if( offp == NULL ) return( NO_IDX );
hi_off = *offp + adj_off;
while( lo_idx <= hi_idx ) {
idx = (lo_idx + hi_idx ) >> 1;
offp = VMBlock( ii, VMADDR( idx ), sizeof( *offp ) );
if( offp == NULL ) return( NO_IDX );
off = *offp + adj_off;
if( want_off < off ) {
hi_idx = idx - 1;
offp = VMBlock( ii, VMADDR( hi_idx ), sizeof( *offp ) );
if( offp == NULL ) return( NO_IDX );
hi_off = *offp + adj_off;
} else if( want_off > off ) {
lo_idx = idx + 1;
offp = VMBlock( ii, VMADDR( lo_idx ), sizeof( *offp ) );
if( offp == NULL ) return( NO_IDX );
lo_off = *offp + adj_off;
} else {
hi_idx = idx;
hi_off = off;
break;
}
}
if( hi_idx < 0 ) return( NO_IDX );
if( hi_off > *best_off ) return( NO_IDX );
*best_off = hi_off;
return( hi_idx );
}
search_result DIPENTRY DIPImpAddrCue( imp_image_handle *ii,
imp_mod_handle im, address addr, imp_cue_handle *ic )
{
cv_directory_entry *cde;
cv_sst_src_module_header *hdr;
cv_sst_src_module_file_table *fp;
cv_sst_src_module_line_number *lp;
off_range *ranges;
unsigned_32 *files;
unsigned_32 *lines;
virt_mem line_base;
virt_mem file_base;
unsigned num_files;
unsigned num_segs;
unsigned file_idx;
unsigned seg_idx;
address curr_addr;
addr_off best_offset;
unsigned pair;
unsigned file_tab_size;
cde = FindDirEntry( ii, im, sstSrcModule );
if( cde == NULL ) return( SR_NONE );
hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) );
if( hdr == NULL ) return( SR_NONE );
ic->im = im;
ranges = __alloca( hdr->cSeg * sizeof( *ranges ) );
lines = __alloca( hdr->cSeg * sizeof( *lines ) );
num_files = hdr->cFile;
file_tab_size = num_files * sizeof( unsigned_32 );
hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) + file_tab_size );
files = __alloca( file_tab_size );
memcpy( files, &hdr->baseSrcFile[0], file_tab_size );
best_offset = (addr_off)-1UL;
for( file_idx = 0; file_idx < num_files; ++file_idx ) {
file_base = files[file_idx] + cde->lfo;
fp = VMBlock( ii, file_base, sizeof( *fp ) );
if( fp == NULL ) return( SR_NONE );
num_segs = fp->cSeg;
fp = VMBlock( ii, file_base, sizeof( *fp )
+ num_segs * (sizeof( unsigned_32 ) + sizeof( off_range ) ) );
if( fp == NULL ) return( SR_NONE );
memcpy( lines, &fp->baseSrcLn[0], num_segs * sizeof( *lines ) );
memcpy( ranges, &fp->baseSrcLn[num_segs], num_segs * sizeof( *ranges ) );
for( seg_idx = 0; seg_idx < num_segs; ++seg_idx ) {
line_base = lines[seg_idx] + cde->lfo;
lp = VMBlock( ii, line_base, sizeof( *lp ) );
if( lp == NULL ) return( SR_NONE );
curr_addr.mach.segment = lp->Seg;
curr_addr.mach.offset = 0;
MapLogical( ii, &curr_addr );
if( DCSameAddrSpace( curr_addr, addr ) != DS_OK ) continue;
if( (ranges[seg_idx].start != 0 || ranges[seg_idx].end != 0)
&& (addr.mach.offset < ranges[seg_idx].start + curr_addr.mach.offset
|| addr.mach.offset > ranges[seg_idx].end + curr_addr.mach.offset) ) {
continue;
}
pair = SearchOffsets( ii, line_base +
offsetof( cv_sst_src_module_line_number, offset[0] ),
lp->cPair, addr.mach.offset, &best_offset, curr_addr.mach.offset );
if( pair != NO_IDX ) {
ic->file = file_base;
ic->line = line_base;
ic->pair = pair;
if( best_offset == addr.mach.offset ) return( SR_EXACT );
}
}
}
if( best_offset == (addr_off)-1UL ) return( SR_NONE );
return( SR_CLOSEST );
}
int DIPENTRY DIPImpCueCmp( imp_image_handle *ii, imp_cue_handle *ic1,
imp_cue_handle *ic2 )
{
ii = ii;
if( ic1->im != ic2->im ) return( ic1->im - ic2->im );
if( ic1->line < ic2->line ) return( -1 );
if( ic1->line > ic2->line ) return( +1 );
return( ic1->pair - ic2->pair );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?