/* * Check for destructors and free the block. */ static void vmFreeBlock( imp_image_handle *ii, virt_page *pg ) { /* check for destructors */ while ( pg->block->first_dtor ) { struct vm_dtor *cur = pg->block->first_dtor; pg->block->first_dtor = cur->next; cur->dtor( ii, cur->user ); DCFree( cur ); } /* free */ DCFree( pg ); }
size_t DIPIMPENTRY( CueFile )( imp_image_handle *ii, imp_cue_handle *ic, char *buff, size_t buff_size ) /************************************************************************/ { char *name; file_walk_name wlk; size_t len; drmem_hdl stmts; drmem_hdl cu_tag; int i; mod_info *modinfo; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ modinfo = IMH2MODI( ii, ic->im ); stmts = modinfo->stmts; cu_tag = modinfo->cu_tag; if( stmts == DRMEM_HDL_NULL || cu_tag == DRMEM_HDL_NULL ) { DCStatus( DS_FAIL ); return( 0 ); } wlk.index = ic->fno; wlk.ret = NULL; wlk.num_dirs = 0; wlk.dirs = NULL; DRWalkLFiles( stmts, ACueFile, &wlk, ACueDir, &wlk ); name = wlk.ret; // Free directory and file table information for( i = 0; i < wlk.num_dirs; i++ ) { DCFree( wlk.dirs[i].name ); } DCFree( wlk.dirs ); if( name == NULL ) { DCStatus( DS_FAIL ); return( 0 ); } // If compilation unit has a DW_AT_comp_dir attribute, we need to // stuff that in front of the file pathname, unless that is absolute len = DRGetCompDirBuff( cu_tag, buff, buff_size ); if( ( len > 1 ) && IsRelPathname( name ) ) { // Ignore empty comp dirs len = NameCopy( buff, "/", buff_size, len ); } else { len = 0; } len = NameCopy( buff, name, buff_size, len ); DCFree( name ); return( len ); }
static int ACueFileNum( void *_fc, dr_line_file *curr ) /*****************************************************/ { file_walk_cue *fc = _fc; int cont; imp_cue_handle *ic; dr_dbg_handle saved; ic = fc->ic; DCFree( curr->name ); ic->a = NilAddr; ic->imx = fc->imx; if( FirstCue( fc->stmts, curr->index, ic ) ) { ic->fno = curr->index; ic->line = 1; ic->col = 0; } saved = DRGetDebug(); fc->wr = fc->wk( fc->ii, ic, fc->d ); DRSetDebug( saved ); if( fc->wr == WR_CONTINUE ) { cont = TRUE; } else { cont = FALSE; } return( cont ); }
void FiniDemand( void ) { DCFree( LastDemand ); LastDemand = NULL; LastDmndSize = 0; TimeStamp = 0; }
dip_status DIGENTRY DIPImpTypeInfo( imp_image_handle *ii, imp_type_handle *it, location_context *lc, dip_type_info *ti ) { /* Fill in the type information for the type handle. The location context is being passed in because it might be needed to calculate the size of the type (variable dimensioned arrays and the like). */ InitTypeHandle( ii, it, lc ); MapImpTypeInfo( &it->typeinfo, ti ); if( ti->kind == TK_INTEGER ) { // this can be removed when 10.5 gets updated char *name; name = DRGetName( it->type ); if( name != NULL ) { if( strcmp( name, "char" ) == 0 || strcmp( name, "unsigned char" ) == 0 ) { ti->kind = TK_CHAR; } DCFree( name ); } } return( DS_OK ); }
dip_status InitDemand( imp_image_handle *ii ) { struct walk_demand d; d.max_size = 0; MyWalkModList( ii, WlkDmnd, &d ); if( d.max_size >= (0x10000UL - sizeof( demand_ctrl )) ) { DCStatus( DS_ERR|DS_INFO_INVALID ); return( DS_ERR|DS_INFO_INVALID ); } if( d.max_size <= LastDmndSize ) return( DS_OK ); if( LastDemand != NULL ) { Unload( LastDemand ); DCFree( LastDemand ); } LastDmndSize = d.max_size; LastDemand = DCAlloc( _demand_size( d.max_size ) ); if( LastDemand == NULL ) { DCStatus( DS_ERR|DS_NO_MEM ); return( DS_ERR|DS_NO_MEM ); } LastDemand->link = NULL; LastDemand->owner = NULL; LastDemand->clear = NULL; LastDemand->locks = 0; return( DS_OK ); }
static void FreeInfBlks( info_block *blk ) { info_block *next; for( ; blk != NULL; blk = next ) { next = blk->next; DCFree( blk ); } }
void ModInfoFini( section_info *inf ) { info_block *blk; pointer_int **lnk_tbl; pointer_int *lnk; for( blk = inf->mod_info; blk != NULL; blk = blk->next ) { DCFree( blk->link ); blk->link = NULL; } lnk_tbl = inf->dmnd_link; if( lnk_tbl != NULL ) { for( ; (lnk = *lnk_tbl) != NULL; ++lnk_tbl ) { DCFree( lnk ); } DCFree( inf->dmnd_link ); inf->dmnd_link = NULL; } }
static void ImpUnloadInfo( imp_image_handle *ii ) { exp_hunk *curr; exp_hunk *next; for( curr = ii->hunks; curr != NULL; curr = next ) { next = curr->next; DCFree( curr ); } ii->hunks = NULL; }
void GblSymFini( section_info *inf ) { info_block *ptr; ptr = inf->gbl; while( ptr != NULL ) { DCFree( ptr->link ); ptr->link = NULL; ptr = ptr->next; } }
void FiniModMap( imp_image_handle *ii ) /****************************************/ // Make the imp_mod_handle to dr_handle map { im_idx i; mod_info *modinfo; ClearMods( ii ); FiniAddrSym( ii->addr_sym ); modinfo = ii->mod_map; for( i = 0; i < ii->mod_count; ++i ) { if( modinfo->name != NULL ) { DCFree( modinfo->name ); } ++modinfo; } DCFree( ii->mod_map ); ii->mod_map = NULL; ii->mod_count = 0; }
void ModInfoFini( section_info *inf ) { info_block *blk; dword **lnk_tbl; dword *lnk; for( blk = inf->mod_info; blk != NULL; blk = blk->next ) { DCFree( blk->link ); blk->link = NULL; } lnk_tbl = inf->dmnd_link; if( lnk_tbl != NULL ) { for( ;; ) { lnk = *lnk_tbl; if( lnk == NULL )break; DCFree( lnk ); ++lnk_tbl; } DCFree( inf->dmnd_link ); inf->dmnd_link = NULL; } }
void VMFini( imp_image_handle *iih ) { int i; int j; virt_page *pg; if( iih->virt != NULL ) { for( i = iih->vm_dir_num-1; i >= 0; --i ) { if( iih->virt[i] != NULL ) { for( j = DIR_SIZE-1; j >= 0; --j ) { pg = iih->virt[i][j]; if( pg != NULL && pg->offset == 0 ) { DCFree( pg ); } } DCFree( iih->virt[i] ); } } DCFree( iih->virt ); iih->virt = NULL; } }
static int ACueFile( void *_info, dr_line_file *curr ) /****************************************************/ { file_walk_name *info = _info; int cont; int i; if( info->index == curr->index ) { if( curr->name ) { if( curr->dir != 0) { for( i = 0; i < info->num_dirs; i++ ) { if( info->dirs[i].index == curr->dir ) break; } if( i < info->num_dirs ) { info->ret = DCAlloc( strlen( curr->name ) + strlen( info->dirs[i].name ) + 2); strcpy( info->ret, info->dirs[i].name ); strcat( info->ret, "/"); strcat( info->ret, curr->name ); DCFree( curr->name ); } else { /* This should be an error, but it isn't fatal as we should * never get here in practice. */ info->ret = curr->name; } } else { info->ret = curr->name; } } else { info->ret = NULL; } cont = FALSE; } else { cont = TRUE; DCFree( curr->name ); } return( cont ); }
static bool FreeBases( void *_lnk ) /*********************************/ //Free bases { inh_vbase **lnk = _lnk; inh_vbase *cur; inh_vbase *next; for( cur = *lnk; cur != NULL; cur = next ) { next = cur->next; DCFree( cur ); } *lnk = NULL; return 0; }
static bool FreeBases( void *_lnk ) /*********************************/ //Free bases { inh_vbase **lnk = _lnk; inh_vbase *cur; inh_vbase *old; cur = *lnk; while( cur != NULL ) { old = cur; cur = cur->next; DCFree( old ); } *lnk = NULL; return 0; }
static void UnloadInfo( imp_image_handle *ii ) { section_info *inf; unsigned i; inf = ii->sect; if( inf != NULL ) { ClearTypeCache( ii ); for( i = ii->num_sects; i > 0; --i, ++inf ) { GblSymFini( inf ); FreeInfBlks( inf->gbl ); ModInfoFini( inf ); FreeInfBlks( inf->mod_info ); AddrInfoFini( inf ); FreeInfBlks( inf->addr_info ); } } DCFree( ii->lang ); }
static unsigned KillPages( imp_image_handle *iih, unsigned i, unsigned j ) { unsigned idx; unsigned num_pages; virt_page *pg; pg = iih->virt[i][j]; num_pages = pg->block->len / VM_PAGE_SIZE; for( idx = 0; idx < num_pages; ++idx ) { if( j >= DIR_SIZE ) { ++i; j = 0; } iih->virt[i][j] = NULL; ++j; } DCFree( pg ); return( num_pages * VM_PAGE_SIZE ); }
static bool AMemLookup( dr_handle var, int index, void *_d ) /**********************************************************/ { type_wlk_lookup *d = _d; imp_sym_handle *is; char *name; unsigned len; name = DRGetName( var ); if( name == NULL ) { DCStatus( DS_FAIL ); return( FALSE ); } len = strlen( name ); if( len == d->li->name.len && d->comp( name, d->li->name.start, len ) == 0 ) { is = DCSymCreate( d->com.ii, d->com.d ); SetSymHandle( (type_wlk *)d, is ); is->sym = var; switch( index ) { case 0: is->sclass = SYM_MEM; break; case 2: is->sclass = SYM_MEMVAR; // static member break; case 3: if( DRGetVirtuality( var ) == DR_VIRTUALITY_VIRTUAL ) { is->sclass = SYM_VIRTF; // virtual func } else if( !DRIsSymDefined( var ) ) { is->sclass = SYM_MEMF; // memfunc decl } else { is->sclass = SYM_MEMVAR; // inlined defn treat like a var } break; } d->sr = SR_EXACT; } DCFree( name ); return( TRUE ); }
static bool AEnumMemLookup( dr_handle var, int index, void *_d ) /**************************************************************/ { type_wlk_lookup *d = _d; imp_sym_handle *is; char *name; unsigned len; index = index; name = DRGetName( var ); if( name == NULL ) { DCStatus( DS_FAIL ); return( FALSE ); } len = strlen( name ); if( len == d->li->name.len && d->comp( name, d->li->name.start, len ) == 0 ) { is = DCSymCreate( d->com.ii, d->com.d ); SetSymHandle( (type_wlk *)d, is ); is->sym = var; d->sr = SR_EXACT; } DCFree( name ); return( TRUE ); }
static void Unload( demand_ctrl *section ) { demand_ctrl **owner; if( section->owner == NULL ) return; if( section == LastDemand ) { if( section->clear != NULL ) { section->clear( section->buff, section->buff + section->size ); } *section->owner = section->save; section->owner = NULL; section->clear = NULL; return; } for( owner = &DemandList; *owner != section; owner = &(*owner)->link ) ; *owner = section->link; if( section->clear != NULL ) { section->clear( section->buff, section->buff + section->size ); } *section->owner = section->save; DCFree( section ); }
void *VMBlock( imp_image_handle *iih, virt_mem start, size_t len ) { unsigned dir_idx; unsigned pg_idx; unsigned tmp_idx; unsigned i; unsigned j; unsigned num_pages; virt_mem pg_start; virt_page *pg; virt_page *zero; loaded_block *block; dir_idx = GET_DIR( start ); if( iih->virt[dir_idx] == NULL ) { if( !InitPageDir( iih, dir_idx ) ) { return( NULL ); } } pg_idx = GET_PAGE( start ); len += start % VM_PAGE_SIZE; pg_start = start & ~(virt_mem)(VM_PAGE_SIZE - 1); pg = iih->virt[dir_idx][pg_idx]; if( pg == NULL || ( pg->block->len - pg->offset ) < len ) { /* unloaded previously loaded block */ if( pg != NULL ) { tmp_idx = dir_idx; /* find first page of the block */ i = pg_idx; for( ;; ) { iih->virt[tmp_idx][i] = NULL; if( pg->offset == 0 ) break; if( i == 0 ) { --tmp_idx; i = DIR_SIZE; } --i; --pg; } DCFree( pg ); } num_pages = BLOCK_FACTOR( len, VM_PAGE_SIZE ); pg = DCAlloc( num_pages * ( sizeof( *pg ) + VM_PAGE_SIZE ) + sizeof( loaded_block ) - 1 ); if( pg == NULL ) { DCStatus( DS_ERR | DS_NO_MEM ); return( NULL ); } /* set up new page table entries */ block = (loaded_block *)&pg[num_pages]; tmp_idx = dir_idx; for( j = pg_idx, i = 0; i < num_pages; ++j, ++i ) { pg[i].block = block; pg[i].offset = i * VM_PAGE_SIZE; if( j >= DIR_SIZE ) { ++tmp_idx; j = 0; } if( iih->virt[tmp_idx] == NULL ) { if( !InitPageDir( iih, tmp_idx ) ) { /* unwind the setup already done */ num_pages = i; for( i = 0; i < num_pages; ++i, ++pg_idx ) { if( pg_idx >= DIR_SIZE ) { ++dir_idx; pg_idx = 0; } iih->virt[dir_idx][pg_idx] = NULL; } DCFree( pg ); return( NULL ); } } if( iih->virt[tmp_idx][j] != NULL ) { /* We just ran into another allocated block, so we have to kill all the pages mapped in by it. We know that if the page pointer is non-NULL, it will be offset==0 since KillPages will clean out the others. */ KillPages( iih, tmp_idx, j ); } iih->virt[tmp_idx][j] = &pg[i]; } /* read in new block */ len = num_pages * VM_PAGE_SIZE; block->len = len; pg_start += iih->bias; if( DCSeek( iih->sym_fp, pg_start, DIG_ORG ) ) { DCStatus( DS_ERR | DS_FSEEK_FAILED ); return( NULL ); } /* last block might be a short read */ if( DCRead( iih->sym_fp, pg->block->data, len ) == DIG_RW_ERROR ) { DCStatus( DS_ERR | DS_FREAD_FAILED ); return( NULL ); } pg = iih->virt[dir_idx][pg_idx]; } ++TimeStamp; if( TimeStamp == 0 ) { /* deal with wrap-around */ for( iih = ImageList; iih != NULL; iih = iih->next_image ) { if( iih->virt != NULL ) { for( i = iih->vm_dir_num; i-- > 0; ) { if( iih->virt[i] != NULL ) { for( j = DIR_SIZE; j-- > 0; ) { zero = iih->virt[i][j]; if( zero != NULL ) { zero->block->time_stamp = 0; } } } } } } ++TimeStamp; } pg->block->time_stamp = TimeStamp; return( &pg->block->data[(start & (VM_PAGE_SIZE - 1)) + pg->offset] ); }
unsigned DIGENTRY DIPImpTypeName( imp_image_handle *ii, imp_type_handle *it, unsigned num, symbol_type *tag, char *buff, unsigned buff_size ) { /* Given the imp_type_handle, copy the name of the type into 'buff'. Do not copy more than 'buff_size' - 1 characters into the buffer and append a trailing '\0' character. Return the real length of the type name (not including the trailing '\0' character) even if you had to truncate it to fit it into the buffer. If something went wrong and you can't get the type name, call DCStatus and return zero. NOTE: the client might pass in zero for 'buff_size'. In that case, just return the length of the module name and do not attempt to put anything into the buffer. Since there can be a "string" of typedef names associated with a type_handle, the 'num' parm indicates which one of the names the client wants returned. Zero is the first type name, one is the second, etc. Fill in '*tag' with ST_ENUM_TAG, ST_UNION_TAG, ST_STRUCT_TAG, ST_CLASS_TAG if the name is a enum, union, struct, or class tag name respectively. If not, set '*tag' to ST_NONE. If the type does not have a name, return zero. */ char *name = NULL; dr_handle dr_type; dr_typeinfo typeinfo; unsigned len; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ ++num; len = 0; dr_type = it->type; while( dr_type != DR_HANDLE_NUL ) { name = DRGetName( dr_type ); if( name != NULL ) { if( --num == 0 ) break; DCFree( name ); } dr_type = DRGetTypeAT( dr_type ); } if( num == 0 ) { DRGetTypeInfo( dr_type, &typeinfo ); switch( typeinfo.kind ) { case DR_TYPEK_ENUM: *tag = ST_ENUM_TAG; break; case DR_TYPEK_STRUCT: *tag = ST_STRUCT_TAG; break; case DR_TYPEK_UNION: *tag = ST_UNION_TAG; break; case DR_TYPEK_CLASS: *tag = ST_CLASS_TAG; break; default: *tag = ST_NONE; break; } len = NameCopy( buff, name, buff_size, 0 ); DCFree( name ); } return( len ); }
void *InfoLoad( imp_image_handle *ii, imp_mod_handle im, unsigned item, unsigned entry, void (*clear)(void *, void *) ) { demand_ctrl *section; demand_info *info; section_info *sect; unsigned long tmpoff; pointer_int *lnk; unsigned size; ++TimeStamp; if( TimeStamp == 0 ) { /* TimeStamp wrapped */ TimeStamp = 1; for(section = DemandList; section != NULL; section = section->link) { section->time_stamp = 0; } } info = &ModPointer( ii, im )->di[ item ]; if( entry >= info->u.entries ) return( NULL ); entry += info->info_off; sect = FindInfo( ii, im ); lnk = &GET_LINK( sect, entry ); if( IS_RESIDENT( *lnk ) ) { section = MK_DMND_PTR( *lnk ); } else { /* section not loaded */ size = DMND_SIZE( sect, entry ); if( (LastDemand->owner == NULL || LastDemand->size < size) && LastDemand->locks == 0 ) { /* keep largest section in LastDemand */ section = LastDemand; Unload( LastDemand ); } else { /* allocate some memory */ section = DCAlloc( _demand_size( size ) ); if( section == NULL ) { if( LastDemand->locks != 0 ) return( NULL ); /* no memory, use last chance */ section = LastDemand; Unload( LastDemand ); } } tmpoff = MK_DMND_OFFSET( *lnk ); if( InfoRead( sect, tmpoff, size, section->buff ) != DS_OK ) { if( section != LastDemand ) DCFree( section ); return( NULL ); } section->size = size; section->locks = 0; section->clear = clear; section->owner = lnk; section->save = *lnk; *lnk = STASH_DMND_PTR( section ); if( section != LastDemand ) { section->link = DemandList; DemandList = section; } } section->time_stamp = TimeStamp; /* for removal priority */ section->locks++; return( section->buff ); }
unsigned DIPENTRY DIPImpCueFile( imp_image_handle *ii, imp_cue_handle *ic, char *buff, unsigned max ) /********************************************************************/ { char *name; char *dir_path; file_walk_name wlk; unsigned len; unsigned dir_len; im_idx imx; dr_handle stmts; dr_handle cu_handle; int i; imx = ic->imx; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ stmts = ii->mod_map[imx].stmts; if( stmts == 0 ) { DCStatus( DS_FAIL ); return( 0 ); } cu_handle = ii->mod_map[imx].cu_tag; if( cu_handle == 0 ) { DCStatus( DS_FAIL ); return( 0 ); } wlk.index = ic->fno; wlk.ret = NULL; wlk.num_dirs = 0; wlk.dirs = NULL; DRWalkLFiles( stmts, ACueFile, &wlk, ACueDir, &wlk ); name = wlk.ret; // Free directory and file table information for( i = 0; i < wlk.num_dirs; i++) DCFree(wlk.dirs[i].name); DCFree(wlk.dirs); if( name == NULL ) { DCStatus( DS_FAIL ); return( 0 ); } // If compilation unit has a DW_AT_comp_dir attribute, we need to // stuff that in front of the file pathname, unless that is absolute dir_len = DRGetCompDirBuff( cu_handle, NULL, 0 ); if( (dir_len > 1) && IsRelPathname( name ) ) { // Ignore empty comp dirs if( max == 0 ) { len = NameCopy( buff, name, max ) + dir_len; } else { dir_path = DCAlloc( dir_len ); if( dir_path == NULL ) { DCStatus( DS_FAIL ); return( 0 ); } DRGetCompDirBuff( cu_handle, dir_path, dir_len ); len = NameCopy( buff, dir_path, max ); DCFree( dir_path ); if( max > len + 1 ) { len += NameCopy( buff + len, "/", 1 + 1 ); len += NameCopy( buff + len, name, max - len ); } } } else { len = NameCopy( buff, name, max ); } DCFree( name ); return( len ); }
static bool ModFill( void *_mod, dr_handle mod_handle ) /*****************************************************/ // fill in mod_handle for dip to dwarf mod map // pick up general info about mod while here for later calls { mod_list *mod = _mod; char fname[MAX_PATH]; char *name; char *path; dr_handle cu_tag; dr_model model; mod_info *modinfo; modinfo = NextModInfo( mod ); modinfo->mod_handle = mod_handle; InitAddrSym( modinfo->addr_sym ); modinfo->addr_size = DRGetAddrSize( mod_handle ); cu_tag = DRGetCompileUnitTag( mod_handle ); modinfo->cu_tag = cu_tag; modinfo->stmts = DRGetStmtList( cu_tag ); path = DRGetName( cu_tag ); if( path != NULL ) { GetModName( path, fname ); DCFree( path ); name = DCAlloc( strlen( fname ) + 1 ); strcpy( name, fname ); } else { name = NULL; } path = DRGetProducer( cu_tag ); if( path != NULL ) { df_ver version; if( strcmp( path, "V2.0 WATCOM" ) == 0 ) { version = VER_V3; } else if( strcmp( path, "V1.0 WATCOM" ) == 0 ) { version = VER_V2; } else if( strcmp( path, "WATCOM" ) == 0 ) { version = VER_V1; } else { version = VER_NONE; } if( mod->version == VER_NONE ) { mod->version = version; } else if( mod->version != version ) { mod->version = VER_ERROR; } DCFree( path ); } modinfo->name = name; model = DRGetMemModelAT( cu_tag ); if( DCCurrMAD() == MAD_X86 ) { switch( model ) { case DR_MODEL_NONE: case DR_MODEL_FLAT: modinfo->is_segment = FALSE; break; default: modinfo->is_segment = TRUE; break; } } else { modinfo->is_segment = FALSE; } modinfo->model = model; modinfo->lang = DRGetLanguageAT( cu_tag ); modinfo->dbg_pch = DRDebugPCHDef( cu_tag ); modinfo->has_pubnames = FALSE; return( TRUE ); }
static bool ModFill( void *_mod, drmem_hdl mod_handle ) /*****************************************************/ // fill in mod_handle for dip to dwarf mod map // pick up general info about mod while here for later calls { mod_list *mod = _mod; char fname[MAX_PATH]; char *name; char *path; drmem_hdl cu_tag; dr_model model; mod_info *modinfo; modinfo = NextModInfo( mod ); modinfo->mod_handle = mod_handle; InitAddrSym( modinfo->addr_sym ); modinfo->addr_size = DRGetAddrSize( mod_handle ); cu_tag = DRGetCompileUnitTag( mod_handle ); modinfo->cu_tag = cu_tag; modinfo->stmts = DRGetStmtList( cu_tag ); path = DRGetName( cu_tag ); if( path != NULL ) { GetModName( path, fname ); DCFree( path ); name = DCAlloc( strlen( fname ) + 1 ); strcpy( name, fname ); } else { name = NULL; } path = DRGetProducer( cu_tag ); if( path != NULL ) { df_ver wat_producer_ver; if( memcmp( path, DWARF_WATCOM_PRODUCER_V3, sizeof( DWARF_WATCOM_PRODUCER_V3 ) - 1 ) == 0 ) { wat_producer_ver = VER_V3; } else if( memcmp( path, DWARF_WATCOM_PRODUCER_V2, sizeof( DWARF_WATCOM_PRODUCER_V2 ) - 1 ) == 0 ) { wat_producer_ver = VER_V2; } else if( memcmp( path, DWARF_WATCOM_PRODUCER_V1, sizeof( DWARF_WATCOM_PRODUCER_V1 ) - 1 ) == 0 ) { wat_producer_ver = VER_V1; } else { wat_producer_ver = VER_NONE; } if( mod->wat_producer_ver == VER_NONE ) { mod->wat_producer_ver = wat_producer_ver; } else if( mod->wat_producer_ver != wat_producer_ver ) { mod->wat_producer_ver = VER_ERROR; } DCFree( path ); } modinfo->name = name; model = DRGetMemModelAT( cu_tag ); if( DCCurrMAD() == MAD_X86 ) { switch( model ) { case DR_MODEL_NONE: case DR_MODEL_FLAT: modinfo->is_segment = false; break; default: modinfo->is_segment = true; break; } } else { modinfo->is_segment = false; } modinfo->model = model; modinfo->lang = DRGetLanguageAT( cu_tag ); modinfo->dbg_pch = DRDebugPCHDef( cu_tag ); modinfo->has_pubnames = false; return( true ); }