示例#1
0
static dip_status LoadDirectory( imp_image_handle *ii, unsigned long off )
{
    unsigned_32                 directory;
    cv_subsection_directory     dir_header;
    unsigned                    block_count;
    unsigned                    i;
    unsigned                    left;
    size_t                      block_size;
    unsigned                    num;

    if( DCSeek( ii->sym_fid, off, DIG_ORG ) != off ) {
        return( DS_ERR|DS_FSEEK_FAILED );
    }
    if( DCRead( ii->sym_fid, &directory, sizeof( directory ) ) != sizeof( directory ) ) {
        return( DS_ERR|DS_FREAD_FAILED );
    }
    if( DCSeek( ii->sym_fid, ii->bias + directory, DIG_ORG ) != (ii->bias + directory) ) {
        return( DS_ERR|DS_FSEEK_FAILED );
    }
    if( DCRead( ii->sym_fid, &dir_header, sizeof( dir_header ) ) != sizeof( dir_header ) ) {
        return( DS_ERR|DS_FREAD_FAILED );
    }
    if( dir_header.cbDirHeader != sizeof( dir_header )
            || dir_header.cbDirEntry  != sizeof( cv_directory_entry ) ) {
        return( DS_ERR|DS_INFO_INVALID );
    }
    ii->dir_count = dir_header.cDir;
    block_count = BLOCK_FACTOR( ii->dir_count, DIRECTORY_BLOCK_ENTRIES );
    ii->directory = DCAlloc( block_count * sizeof( cv_directory_entry * ) );
    if( ii->directory == NULL ) {
        return( DS_ERR|DS_NO_MEM );
    }
    memset( ii->directory, 0, block_count * sizeof( cv_directory_entry * ) );
    i = 0;
    left = ii->dir_count;
    for( ;; ) {
        num = left;
        if( num > DIRECTORY_BLOCK_ENTRIES )
            num = DIRECTORY_BLOCK_ENTRIES;
        block_size = num * sizeof( cv_directory_entry );
        ii->directory[i] = DCAlloc( block_size );
        if( ii->directory[i] == NULL ) {
            return( DS_ERR|DS_NO_MEM );
        }
        if( DCRead( ii->sym_fid, ii->directory[i], block_size ) != block_size ) {
            return( DS_ERR|DS_FREAD_FAILED );
        }
        ++i;
        left -= num;
        if( left == 0 ) {
            break;
        }
    }
    return( DS_OK );
}
示例#2
0
/*
 * Adds a destructor to a block.
 */
dip_status VMAddDtor( imp_image_handle *ii, virt_mem start,
                      void ( *dtor )( imp_image_handle *ii, void *user ),
                      void *user )
{
    unsigned            dir_idx;
    unsigned            pg_idx;
    virt_page           *pg;

    /* locate the block. */
    dir_idx = GET_DIR( start );
    if( ii->virt[dir_idx] != NULL ) {
        pg_idx = GET_PAGE( start );
        pg = ii->virt[dir_idx][pg_idx];
        if( pg != NULL ) {
            /* create a new dtor node and link it in */
            vm_dtor *node = DCAlloc( sizeof( *node ) );
            if( node != NULL ) {
                node->user = user;
                node->dtor = dtor;
                node->next = pg->block->first_dtor;
                pg->block->first_dtor = node;
                return( DS_OK );
            }
            return( DS_ERR | DS_NO_MEM );
        }
    }

    return( DS_ERR | DS_FAIL );
}
示例#3
0
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 );
}
示例#4
0
static int InitPageDir( imp_image_handle *iih, unsigned dir_idx )
{
    iih->virt[dir_idx] = DCAlloc( sizeof( virt_page * ) * DIR_SIZE );
    if( iih->virt[dir_idx] == NULL ) {
        DCStatus( DS_ERR | DS_NO_MEM );
        return( 0 );
    }
    memset( iih->virt[dir_idx], 0, sizeof( virt_page * ) * DIR_SIZE );
    return( 1 );
}
示例#5
0
dip_status VMInit( imp_image_handle *iih, unsigned long size )
{
    iih->vm_dir_num = BLOCK_FACTOR( size, DIR_SIZE * VM_PAGE_SIZE );
    iih->virt = DCAlloc( iih->vm_dir_num * sizeof( *iih->virt ) );
    if( iih->virt == NULL ) {
        DCStatus( DS_ERR | DS_NO_MEM );
        return( DS_ERR | DS_NO_MEM );
    }
    memset( iih->virt, 0, iih->vm_dir_num * sizeof( *iih->virt ) );
    return( DS_OK );
}
示例#6
0
static bool ACueFile( void *_info, dr_line_file *curr )
/*****************************************************/
{
    file_walk_name  *info = _info;
    bool            cont;
    int             i;

    cont = true;
    if( info->index == curr->index ) {
        if( curr->name != NULL ) {
            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 );
                } else {
                    /* This should be an error, but it isn't fatal as we should
                     * never get here in practice.
                     */
                    info->ret = DCAlloc( strlen( curr->name ) + 1 );
                    strcpy( info->ret, curr->name );
                }
            } else {
                info->ret = DCAlloc( strlen( curr->name ) + 1 );
                strcpy( info->ret, curr->name );
            }
        } else {
            info->ret = NULL;
        }
        cont = false;
    }
    return( cont );
}
示例#7
0
/*
 * Deals with LX and LE images.
 * We must try grab information from the object table.
 */
static dip_status FindHLLInLXImage( imp_image_handle *ii, unsigned long nh_off )
{
    union  {
        os2_flat_header flat;
        object_record   obj;
    }                   buf;
    dip_status          rc;

    /* read the header */
    rc = DCReadAt( ii->sym_file, &buf.flat, sizeof( buf.flat ), nh_off );
    if( rc & DS_ERR ) {
        return( rc );
    }
    rc = DS_FAIL;
    if( buf.flat.debug_off && buf.flat.debug_len ) {
        ii->is_32bit = 1;
        rc = FoundHLLSign( ii, buf.flat.debug_off, buf.flat.debug_len );
        if( rc == DS_OK ) {
            unsigned i;

            /*
             * Get segment info from the object table.
             */
            if ( DCSeek( ii->sym_file, buf.flat.objtab_off + nh_off, DIG_ORG )
              != buf.flat.objtab_off + nh_off ) {
                return( DS_ERR | DS_FSEEK_FAILED );
            }

            ii->seg_count = buf.flat.num_objects;
            ii->segments = DCAlloc( sizeof( hllinfo_seg ) * ii->seg_count );
            if( ii->segments == NULL ) {
                return( DS_ERR | DS_NO_MEM );
            }

            for( i = 0; i < ii->seg_count; i++ ) {
                if( DCRead( ii->sym_file, &buf.obj, sizeof( buf.obj ) )
                 != sizeof( buf.obj )) {
                    return( DS_ERR | DS_FREAD_FAILED );
                }
                ii->segments[i].is_executable = !!( buf.obj.flags & OBJ_EXECUTABLE );
                ii->segments[i].is_16bit = !( buf.obj.flags & OBJ_BIG );
                ii->segments[i].ovl = 0;
                ii->segments[i].map.offset = 0;
                ii->segments[i].map.segment = i + 1;
                ii->segments[i].size = buf.obj.size;
                ii->segments[i].address = buf.obj.addr;
            }
        }
    }
    return( rc );
}
示例#8
0
static bool ACueDir( void *_info, dr_line_dir *curr )
/***************************************************/
{
    file_walk_name  *info = _info;

    if( info != NULL ) {
        info->dirs = DCRealloc( info->dirs, sizeof( dr_line_dir ) * (info->num_dirs + 1) );
        info->dirs[info->num_dirs].index = curr->index;
        info->dirs[info->num_dirs].name = DCAlloc( strlen( curr->name ) + 1 );
        strcpy( info->dirs[info->num_dirs].name, curr->name );
        info->num_dirs++;
    }
    return( true );
}
示例#9
0
static dip_status LoadMapping( imp_image_handle *ii )
{
    cv_directory_entry  *cde;
    cv_sst_seg_map      *map;
    size_t              size;

    cde = FindDirEntry( ii, IMH_GBL, sstSegMap );
    if( cde == NULL )
        return( DS_ERR|DS_INFO_INVALID );
    map = VMBlock( ii, cde->lfo, cde->cb );
    if( map == NULL )
        return( DS_ERR|DS_FAIL );
    size = map->cSegLog * sizeof( map->segdesc[0] );
    ii->mapping = DCAlloc( size );
    if( ii->mapping == NULL )
        return( DS_ERR|DS_NO_MEM );
    map = VMBlock( ii, cde->lfo, cde->cb ); /* malloc might have unloaded */
    memcpy( ii->mapping, &map->segdesc[0], size );
    ii->map_count = map->cSegLog;
    return( DS_OK );
}
示例#10
0
static bool AddBase( drmem_hdl base, inh_vbase **lnk )
/****************************************************/
//if base not in list add return false
{
    inh_vbase   *cur;

    while( (cur = *lnk) != NULL ){
        if( base <= cur->base ){
            if( base == cur->base ){
                return( false );
            }
            break;
        }
        lnk = &cur->next;
    }
    cur = DCAlloc( sizeof( *cur ) );
    cur->base = base;
    cur->next = *lnk;
    *lnk = cur;
    return( true );
}
示例#11
0
static bool AddBase( dr_handle base, inh_vbase **lnk )
/****************************************************/
//if base not in list add return FALSE
{
    inh_vbase   *cur;

    while( (cur = *lnk) != NULL ) {
        if( base <= cur->base ) {
            if( base == cur->base ) {
                return( FALSE);
            }
            break;
        }
        lnk = &cur->next;
    }
    cur = DCAlloc( sizeof( *cur ) );
    cur->base = base;
    cur->next = *lnk;
    *lnk = cur;
    return( TRUE );
}
示例#12
0
static void *HunkAlloc( imp_image_handle *ii, size_t size )
{
    exp_hunk    *hunk;
    size_t      alloc;

    size = ROUND_UP( size, sizeof( void * ) );
    hunk = ii->hunks;
    if( hunk == NULL || size > hunk->left ) {
        alloc = HUNK_SIZE;
        if( alloc < size )
            alloc = size;
        hunk = DCAlloc( (sizeof( *hunk ) - HUNK_SIZE) + alloc );
        if( hunk == NULL )
            return( NULL );
        hunk->next = ii->hunks;
        ii->hunks = hunk;
        hunk->left = alloc;
    }
    hunk->left -= size;
    return( &hunk->data[ hunk->left ] );
}
示例#13
0
seg_cue *InitSegCue( cue_list *ctl, addr_seg seg, addr_off offset )
/*****************************************************************/
/* Keep in asending order  seg:offset */
{
    seg_cue     *curr;
    seg_cue     **lnk;

    for( lnk = &ctl->head; (curr = *lnk) != NULL; lnk = &curr->next ) {
        if( seg < curr->seg || ( seg == curr->seg && offset < curr->low ) ) {
            break;
        }
    }
    curr = DCAlloc( sizeof( *curr ) );
    curr->seg = seg;
    curr->low = offset;
    curr->high = offset;
    curr->count = 0;
    curr->head = NULL;
    curr->next = *lnk;
    *lnk = curr;
    return( curr );
}
示例#14
0
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 );
}
示例#15
0
/*
 * AllocLinkTable - allocate the demand load link table
 *
 */
static dip_status AllocLinkTable( section_info *inf, unsigned long num_links,
                                unsigned long first_link )
{
    dword               **lnk_tbl;
    dword               *lnk;
    mod_table           *tbl;
    unsigned            num;
    unsigned long       count;
    unsigned            i;
    unsigned            d;
    mod_info            *mod;
    unsigned            tbl_entries;
    dword               end;
    info_block          *blk;

    tbl_entries = ((num_links+(MAX_LINK_ENTRIES-1)) / MAX_LINK_ENTRIES) + 1;
    lnk_tbl = DCAlloc( tbl_entries * sizeof( dword * ) );
    if( lnk_tbl == NULL ) {
        DCStatus( DS_ERR|DS_NO_MEM );
        return( DS_ERR|DS_NO_MEM );
    }
    for( i = 0; i < tbl_entries; ++i ) lnk_tbl[i] = NULL;
    inf->dmnd_link = lnk_tbl;
    i = 0;
    count = num_links;
    while( count != 0 ) {
        num = (count>MAX_LINK_ENTRIES) ? MAX_LINK_ENTRIES : count;
        lnk = DCAlloc( num*sizeof(dword));
        if( lnk == NULL ) {
            DCStatus( DS_ERR|DS_NO_MEM );
            return( DS_ERR|DS_NO_MEM );
        }
        lnk_tbl[i++] = lnk;
        if( !inf->ctl->v2 ) {
            if( DCRead(inf->ctl->sym_file,lnk,num*sizeof(dword))!=num*sizeof(dword)) {
                DCStatus( DS_ERR|DS_FREAD_FAILED );
                return( DS_ERR|DS_FREAD_FAILED );
            }
        }
        count -= num;
    }
    lnk = *lnk_tbl;
    num = 0;
    count = 0;
    for( d = DMND_FIRST; d < DMND_NUM; ++d ) {
        for( blk = inf->mod_info; blk != NULL; blk = blk->next ) {
            tbl = blk->link;
            for( i = 0; i < tbl->count; ++i ) {
                mod = (mod_info *)((byte *)blk->info + tbl->mod_off[i]);
                if( inf->ctl->v2 ) {
                    if( mod->di[d].u.size != 0 ) {
                        if( num >= MAX_LINK_ENTRIES ) {
                            lnk = *++lnk_tbl;
                            num = 0;
                        }
                        lnk[num] = mod->di[d].info_off;
                        end = lnk[num] + mod->di[d].u.size;
                        mod->di[d].u.entries = 1;
                        mod->di[d].info_off = count;
                        ++num;
                        ++count;
                    }
                } else {
                    if( mod->di[d].u.entries != 0 ) {
                        mod->di[d].info_off =
                        (mod->di[d].info_off-first_link)/sizeof(dword);
                    }
                }
            }
        }
    }
    if( inf->ctl->v2 ) {
        if( num >= MAX_LINK_ENTRIES ) {
            lnk = *++lnk_tbl;
            num = 0;
        }
        lnk[num] = end;
    }
    return( DS_OK );
}
示例#16
0
/*
 * AdjustMods - adjust the demand info offsets in all the modules
 *            - allocate module index table
 *            - allocate demand load link table
 */
dip_status AdjustMods( section_info *inf, unsigned long adjust )
{
    info_block          *blk;
    unsigned            count;
    unsigned            mod_off;
    mod_table           *tbl;
    mod_info            *mod;
    dword               num_links;
    dword               first_link;
    dword               last_link;
    demand_kind         dk;
    unsigned            num;
    pointer_int         *lnk;
    pointer_int         **lnk_tbl;
    unsigned long       off;
    dip_status          ok;

    last_link = 0;
    first_link = (dword)-1L;
    num_links = 1;
    for( blk = inf->mod_info; blk != NULL; blk = blk->next ) {
        mod = (mod_info *)blk->info;
        count = 0;
        for( mod_off = 0; mod_off < blk->size; mod_off += MODINFO_SIZE( (byte *)mod + mod_off ) ) {
            ++count;
        }
        tbl = DCAlloc( sizeof( mod_table ) + ( count - 1 ) * sizeof( mod_info * ) );
        if( tbl == NULL ) {
            DCStatus( DS_ERR|DS_NO_MEM );
            return( DS_ERR|DS_NO_MEM );
        }
        tbl->count = count;
        blk->link = tbl;
        count = 0;
        for( mod_off = 0; mod_off < blk->size; mod_off += MODINFO_SIZE( mod ) ) {
            tbl->mod_off[count++] = mod_off;
            mod = (mod_info *)((byte *)blk->info + mod_off);
            for( dk = 0; dk < MAX_DMND; ++dk ) {
                if( inf->ctl->v2 ) {
                    if( mod->di[dk].u.size != 0 ) {
                        ++num_links;
                    }
                } else {
                    if( mod->di[dk].u.entries != 0 ) {
                        num_links = mod->di[dk].info_off;
                        if( first_link > num_links ) {
                            first_link = num_links;
                        }
                        num_links += mod->di[dk].u.entries * sizeof( pointer_int );
                        if( last_link < num_links ) {
                            last_link = num_links;
                        }
                    }
                }
            }
        }
    }
    if( !inf->ctl->v2 ) {
        off = first_link + adjust;
        if( DCSeek( inf->ctl->sym_fid, off, DIG_ORG) != off ) {
            DCStatus( DS_ERR|DS_FSEEK_FAILED );
            return( DS_ERR|DS_FSEEK_FAILED );
        }
        num_links = (last_link - first_link) / sizeof( pointer_int ) + 2;
    }
    ok = AllocLinkTable( inf, num_links, first_link );
    if( ok != DS_OK )
        return( ok );
    num = 0;
    lnk_tbl = inf->dmnd_link;
    lnk = *lnk_tbl;
    for( ; num_links-- > 0; ) {
        if( num >= MAX_LINK_ENTRIES ) {
            lnk = *++lnk_tbl;
            num = 0;
        }
        /*
         * shift over one bit so as to leave the lower bit
         * clear for testing if it is allocated or not
         */
        lnk[num] = (lnk[num] + adjust) << 1;
        ++num;
    }
    return( DS_OK );
}
示例#17
0
/*
 * AllocLinkTable - allocate the demand load link table
 *
 */
static dip_status AllocLinkTable( section_info *inf, dword num_links, dword first_link )
{
    pointer_int         **lnk_tbl;
    pointer_int         *lnk;
    mod_table           *tbl;
    unsigned            num;
    dword               count;
    unsigned            i;
    demand_kind         dk;
    mod_info            *mod;
    unsigned            tbl_entries;
    pointer_int         end = 0;
    info_block          *blk;
#if defined( _M_X64 )
    unsigned            j;
#endif

    tbl_entries = ( ( num_links + ( MAX_LINK_ENTRIES - 1 ) ) / MAX_LINK_ENTRIES ) + 1;
    lnk_tbl = DCAlloc( tbl_entries * sizeof( pointer_int * ) );
    if( lnk_tbl == NULL ) {
        DCStatus( DS_ERR|DS_NO_MEM );
        return( DS_ERR|DS_NO_MEM );
    }
    for( i = 0; i < tbl_entries; ++i )
        lnk_tbl[i] = NULL;
    inf->dmnd_link = lnk_tbl;
    i = 0;
    num = MAX_LINK_ENTRIES;
    for( count = num_links; count > 0; count -= num ) {
        if( num > count )
            num = count;
        lnk = DCAlloc( num * sizeof( pointer_int ) );
        if( lnk == NULL ) {
            DCStatus( DS_ERR|DS_NO_MEM );
            return( DS_ERR|DS_NO_MEM );
        }
        lnk_tbl[i++] = lnk;
        if( !inf->ctl->v2 ) {
            if( DCRead( inf->ctl->sym_fid, lnk, num * sizeof( dword ) ) != num * sizeof( dword ) ) {
                DCStatus( DS_ERR|DS_FREAD_FAILED );
                return( DS_ERR|DS_FREAD_FAILED );
            }
#if defined( _M_X64 )
            for( j = num; j-- > 0; ) {
                lnk[j] = ((dword *)lnk)[j];
            }
#endif
        }
    }
    lnk = *lnk_tbl;
    num = 0;
    count = 0;
    for( dk = 0; dk < MAX_DMND; ++dk ) {
        for( blk = inf->mod_info; blk != NULL; blk = blk->next ) {
            tbl = blk->link;
            for( i = 0; i < tbl->count; ++i ) {
                mod = (mod_info *)((byte *)blk->info + tbl->mod_off[i]);
                if( inf->ctl->v2 ) {
                    if( mod->di[dk].u.size != 0 ) {
                        if( num >= MAX_LINK_ENTRIES ) {
                            lnk = *++lnk_tbl;
                            num = 0;
                        }
                        lnk[num] = mod->di[dk].info_off;
                        end = lnk[num] + mod->di[dk].u.size;
                        mod->di[dk].u.entries = 1;
                        mod->di[dk].info_off = count;
                        ++num;
                        ++count;
                    }
                } else {
                    if( mod->di[dk].u.entries != 0 ) {
                        mod->di[dk].info_off =
                        ( mod->di[dk].info_off - first_link ) / sizeof( pointer_int );
                    }
                }
            }
        }
    }
    if( inf->ctl->v2 ) {
        if( num >= MAX_LINK_ENTRIES ) {
            lnk = *++lnk_tbl;
            num = 0;
        }
        lnk[num] = end;
    }
    return( DS_OK );
}
示例#18
0
/*
 * AdjustMods - adjust the demand info offsets in all the modules
 *            - allocate module index table
 *            - allocate demand load link table
 */
dip_status AdjustMods( section_info *inf, unsigned long adjust )
{
    info_block          *blk;
    unsigned            count;
    unsigned            mod_off;
    mod_table           *tbl;
    mod_info            *mod;
    unsigned long       num_links;
    unsigned long       first_link;
    unsigned long       last_link;
    unsigned            d;
    unsigned            num;
    dword               *lnk;
    dword               **lnk_tbl;
    unsigned long       off;
    dip_status          ok;

    last_link = 0;
    first_link = ~0;
    num_links = 1;
    for( blk = inf->mod_info; blk != NULL; blk = blk->next ) {
        count = 0;
        for( mod_off = 0; mod_off < blk->size;
                mod_off += sizeof( mod_info ) + mod->name[0] ) {
            ++count;
            mod = (mod_info *)((byte *)blk->info + mod_off);
        }
        tbl = DCAlloc( sizeof(mod_table) + (count-1)*sizeof(mod_info *) );
        if( tbl == NULL ) {
            DCStatus( DS_ERR|DS_NO_MEM );
            return( DS_ERR|DS_NO_MEM );
        }
        tbl->count = count;
        blk->link = tbl;
        count = 0;
        for( mod_off = 0; mod_off < blk->size;
                mod_off += sizeof( mod_info ) + mod->name[0] ) {
            tbl->mod_off[count++] = mod_off;
            mod = (mod_info *)((byte *)blk->info + mod_off);
            for( d = DMND_FIRST; d < DMND_NUM; ++d ) {
                if( inf->ctl->v2 ) {
                    if( mod->di[d].u.size != 0 ) ++num_links;
                } else {
                    if( mod->di[d].u.entries != 0 ) {
                        num_links = mod->di[d].info_off;
                        if( num_links < first_link ) {
                            first_link = num_links;
                        }
                        num_links += mod->di[d].u.entries
                                        * sizeof(dword);
                        if( num_links > last_link ) {
                            last_link = num_links;
                        }
                    }
                }
            }
        }
    }
    if( !inf->ctl->v2 ) {
        off = first_link + adjust;
        if( DCSeek( inf->ctl->sym_file, off, DIG_ORG) != off ) {
            DCStatus( DS_ERR|DS_FSEEK_FAILED );
            return( DS_ERR|DS_FSEEK_FAILED );
        }
        num_links = (last_link - first_link) / sizeof( dword ) + 2;
    }
    ok = AllocLinkTable( inf, num_links, first_link );
    if( ok != DS_OK ) return( ok );
    num = 0;
    lnk_tbl = inf->dmnd_link;
    lnk = *lnk_tbl;
    for( ;; ) {
        if( num_links == 0 ) break;
        if( num >= MAX_LINK_ENTRIES ) {
            lnk = *++lnk_tbl;
            num = 0;
        }
        /*
         * shift over one bit so as to leave the lower bit
         * clear for testing if it is allocated or not
         */
        lnk[num] = (lnk[num] + adjust) << 1;
        ++num;
        --num_links;
    }
    return( DS_OK );
}
示例#19
0
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 );
}
示例#20
0
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] );
}
示例#21
0
/*
 * Loads the HLL directory.
 *
 * 'offent' is the file offset of the first directory entry.
 */
static dip_status LoadDirectory( imp_image_handle *ii, unsigned long offent )
{
    unsigned                block_count;
    unsigned                i;
    unsigned                left;
    size_t                  block_size;
    unsigned                num;

    /*
     * Read the directory entries. We're using a two-level table here,
     * probably to avoid allocating big chunks of memory...
     */
    block_count = BLOCK_FACTOR( ii->dir_count, DIRECTORY_BLOCK_ENTRIES );
    ii->directory = DCAlloc( block_count * sizeof( void * ) );
    if( ii->directory == NULL ) {
        return( DS_ERR | DS_NO_MEM );
    }
    memset( ii->directory, 0, block_count * sizeof( void * ) );

    /* skip to the first entry */
    if( DCSeek( ii->sym_file, offent, DIG_ORG ) != offent) {
        return( DS_ERR | DS_FSEEK_FAILED );
    }

    i = 0;
    left = ii->dir_count;
    do {
        num = left;
        if( num > DIRECTORY_BLOCK_ENTRIES ) {
            num = DIRECTORY_BLOCK_ENTRIES;
        }
        block_size = num * sizeof( hll_dir_entry );
        ii->directory[i] = DCAlloc( block_size );
        if( ii->directory[i] == NULL ) {
            return( DS_ERR | DS_NO_MEM );
        }
        if( ii->format_lvl >= HLL_LVL_NB04 ) {
            if( DCRead( ii->sym_file, ii->directory[i], block_size ) != block_size ) {
                return( DS_ERR | DS_FREAD_FAILED );
            }
        } else {
            /* Slow but simple. */
            int             j;
            hll_dir_entry  *ent = ii->directory[i];

            for( j = 0; j < num; j++, ent++ ) {
                cv3_dir_entry cv3ent;
                if( DCRead( ii->sym_file, &cv3ent, sizeof( cv3ent ) ) != sizeof( cv3ent ) ) {
                    return( DS_ERR | DS_FREAD_FAILED );
                }
                ent->subsection = cv3ent.subsection;
                ent->iMod       = cv3ent.iMod;
                ent->lfo        = cv3ent.lfo;
                ent->cb         = cv3ent.cb;
            }
        }
        ++i;
        left -= num;
    } while( left != 0 );
    return( DS_OK );
}
示例#22
0
/*
 * Load debug info if it's in the HLL/CV format.
 */
dip_status DIGENTRY DIPImpLoadInfo( dig_fhandle h, imp_image_handle *ii )

{
    dip_status      rc;

    /* Init the module handle. */
    memset( ii, 0, sizeof( *ii ) );
    ii->mad = MAD_X86;                  /* No known non-x86 support */
    ii->sym_file = h;
    ii->is_32bit = 1;
    ii->format_lvl = HLL_LVL_NB04;
    ii->next_image = ImageList;
    ImageList = ii;

    /* Read basic HLL and executable image bits. */
    rc = FindHLL( ii );
    if( rc == DS_OK ) {
        rc = VMInit( ii, ii->size );
    }

    /* Make sure we've got segment mappings. (FIXME: scan module headers) */
    if( rc == DS_OK && !ii->segments ) {
        ii->seg_count = 2;
        ii->segments = DCAlloc( sizeof( hllinfo_seg ) * ii->seg_count );
        if( ii->segments != NULL ) {
            memset( ii->segments, 0, sizeof( hllinfo_seg ) * ii->seg_count );
            ii->segments[0].is_executable = 1;
            ii->segments[0].map.segment = 1;
            ii->segments[1].map.segment = 2;
            ii->segments[0].size = ii->segments[1].size = 0x00400000; /* 4MB */
            ii->segments[0].address = ii->segments[1].address = 0;
        } else{
            rc = DS_ERR | DS_NO_MEM;
        }
    }

    /* Locate global types. If none, we've types per module. */
    if( rc == DS_OK ) {
        /* FIXME
        hll_debug_dir *cde;
        cde = FindDirEntry( ii, IMH_GBL, sstGlobalTypes );
        if( cde != NULL ) {
            hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) );
            if( hdr == NULL ) {
                Cleanup( ii );
                return( DS_ERR | DS_FAIL );
            }
            ii->types_base = cde->lfo
                + offsetof( cv_sst_global_types_header, offType )
                + hdr->cType * sizeof( hdr->offType[0] );
        }
        */
    }

    /* We're done - clean up on failure. */
    if( rc != DS_OK ) {
        DCStatus( rc );
        Cleanup( ii );
    }
    return( rc );
}
示例#23
0
/*
 * Deals with 32-bit PE images.
 */
static dip_status FindHLLInPEImage( imp_image_handle *ii, unsigned long nh_off )
{
    dip_status          rc;
    unsigned_32         debug_rva;
    unsigned_32         debug_len;
    unsigned_32         image_base;
    unsigned            i;
    unsigned_32         sh_off;
    union {
        char            sig[HLL_SIG_SIZE]; /* ASSUMES >= 4 */
        unsigned_16     sig_16;
        unsigned_32     sig_32;
        pe_header       pe;
        pe_object       sh;
        debug_directory dbg_dir;
    }                   buf;

    /* read the header */
    rc = DCReadAt( ii->sym_file, &buf.pe, sizeof( buf.pe ), nh_off );
    if( rc & DS_ERR ) {
        return( rc );
    }

    debug_rva = buf.pe.table[ PE_TBL_DEBUG ].rva;
    debug_len = buf.pe.table[ PE_TBL_DEBUG ].size;
    if( !debug_rva || !debug_len ) {
        return( DS_FAIL );
    }
    ii->is_32bit = 1;
    image_base = buf.pe.image_base;

    /*
     * Translate the rva to a file offset and read necessary
     * segment information at the same time.
     */
    ii->seg_count = buf.pe.num_objects;
    ii->segments = DCAlloc( sizeof( hllinfo_seg ) * buf.pe.num_objects );
    if( ii->segments == NULL ) {
        return( DS_ERR | DS_NO_MEM );
    }

    sh_off = nh_off /* vv -- watcom mixes the headers :-( */
           + offsetof( pe_header, flags ) + sizeof( buf.pe.flags )
           + buf.pe.nt_hdr_size;

    for ( i = 0; i < ii->seg_count; i++, sh_off += sizeof( buf.sh ) ) {
        rc = DCReadAt( ii->sym_file, &buf.sh, sizeof( buf.sh ), sh_off );
        if ( rc & DS_ERR ) {
            return( rc );
        }

        /* collect segment info. */
        ii->segments[i].is_executable = !!( buf.sh.flags & PE_OBJ_CODE );
        ii->segments[i].ovl = 0;
        ii->segments[i].map.offset = 0;
        ii->segments[i].map.segment = i + 1;
        ii->segments[i].size = buf.sh.virtual_size; // FIXME: alignment?
        ii->segments[i].address = buf.sh.rva + image_base;

        /* is the debug directory section? */
        if( !ii->bias
         && debug_rva - buf.sh.rva < buf.sh.virtual_size ) {
            unsigned_32 debug_off;
            int         left;
            debug_off = buf.sh.physical_offset + debug_rva - buf.sh.rva;

            /*
             * The IBM linker screw up here. It will omit the debug
             * directory and put the debug info there instead.
             * So, before scanning we'll have to check for any HLL sign.
             */
            rc = DCReadAt( ii->sym_file, &buf.dbg_dir, sizeof( buf.dbg_dir ), debug_off );
            if( rc & DS_ERR ) {
                return( rc );
            }
            if( IsHllSignature( &buf ) ) {
                rc = FoundHLLSign( ii, debug_off, debug_len );
            } else {
                left = debug_len / sizeof( debug_directory );
                if( left < 16 )
                    left = 16;
                for ( ;; ) {
                    if( buf.dbg_dir.debug_type == DEBUG_TYPE_CODEVIEW ) {
                        /* found something? */
                        rc = FoundHLLSign( ii, buf.dbg_dir.data_seek, buf.dbg_dir.data_seek );
                        if( rc == DS_OK || rc & DS_ERR ) {
                            break;
                        }
                    }

                    /* next */
                    --left;
                    if( left <= 0) {
                        break;
                    }
                    if ( DCRead( ii->sym_file, &buf.dbg_dir, sizeof( buf.dbg_dir ) ) != sizeof( buf.dbg_dir ) ) {
                        break;
                    }
                }
            }
            if( rc & DS_ERR ) {
                return( rc );
            }
        }
    }

    return( ii->bias ? DS_OK : DS_FAIL );
}
示例#24
0
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 );
}
示例#25
0
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 );
}