loadflat.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 564 行 · 第 1/2 页

C
564
字号
                        bundle_fwd.value     = dll->u.entry->num;
                    }
                    WriteLoad( &bundle_fwd, sizeof( flat_bundle_entryfwd ) );
                } else {
                    // 32-bit entry
                    bundle_item.e32_flags = (start->iopl_words << IOPL_WORD_SHIFT);
                    if( start->isexported ) bundle_item.e32_flags |= ENTRY_EXPORTED;
                    bundle_item.e32_offset = start->addr.off;
                    WriteLoad( &bundle_item, sizeof( flat_bundle_entry32 ) );
                }
            }
        }
    }
    PadLoad( 1 );
    return( size + 1 );
}

static unsigned_32 WriteRelocSize( void *** reloclist, unsigned_32 size,
                                                        unsigned limit )
/**********************************************************************/
{
    void **     rptr;

    if( reloclist != NULL ) {
        rptr = *reloclist;
    } else {
        rptr = NULL;
    }
    while( limit > 0 ) {
        WriteLoad( &size, sizeof( unsigned_32 ) );
        if( rptr != NULL ) {
            /* first one for external fixups */
            size += RelocSize( *rptr++ );
            /* second for internals */
            size += RelocSize( *rptr++ );
        }
        limit--;
    }
    return( size );
}

static unsigned_32 WriteFixupTables( os2_flat_header *header, unsigned long loc)
/******************************************************************************/
/* dump the fixup page table and the fixup record table */
{
    unsigned_32     size;
    unsigned_32     numpages;
    unsigned_32     numentries;
    group_entry *   group;
    void ***        reloclist;
    unsigned_32     highidx;
    unsigned        lowidx;

    header->fixpage_off = loc;
    numentries = 0;
    size = 0;
    for( group = Groups; group != NULL; group = group->next_group ) {
        reloclist = group->g.grp_relocs;
        numpages = PAGE_COUNT( group->size );
        numentries += numpages;
        highidx = OSF_RLIDX_HIGH(numpages);
        while( highidx > 0 ) {
            size = WriteRelocSize( reloclist, size, OSF_RLIDX_MAX );
            highidx--;
            if( reloclist != NULL ) reloclist++;
        }
        lowidx = OSF_RLIDX_LOW(numpages);
        if( lowidx > 0 ) {
            size = WriteRelocSize( reloclist, size, lowidx );
        }
    }
    WriteLoad( &size, sizeof( unsigned_32 ) );
    ++numentries;
    /* now that the page table is dumped, do the fixups. */
    header->fixrec_off = loc + numentries * sizeof( unsigned_32 );
    size += numentries * sizeof( unsigned_32 );
    for( group = Groups; group != NULL; group = group->next_group ) {
        TraverseOS2RelocList( group, DumpRelocList );
    }
    return( size );
}

static unsigned WriteDataPages( unsigned long loc )
/*************************************************/
/* write the enumerated data pages */
{
    group_entry *group;
    unsigned    last_page;
    unsigned    size;

    last_page = 0;
    for( group = Groups; group != NULL; group = group->next_group) {
        if( group->size != 0 ) {
            if( last_page != 0 ) {
                if( FmtData.type & (MK_OS2_LE|MK_WIN_VXD) ) {
                    size = OSF_DEF_PAGE_SIZE - last_page;
                } else {
                    size = ROUND_SHIFT(last_page, FmtData.u.os2.segment_shift)
                             - last_page;
                }
                PadLoad( size );
                loc += size;
            }
            WriteGroupLoad( group );
            loc += group->size;
            last_page = group->size & (OSF_DEF_PAGE_SIZE-1);
        }
    }
    if( last_page == 0 ) {
        last_page = OSF_DEF_PAGE_SIZE;
    } else if( !(FmtData.type & (MK_OS2_LE|MK_WIN_VXD)) ) {
        PadLoad( ROUND_SHIFT( last_page, FmtData.u.os2.segment_shift )
                             - last_page );
    }
    return( last_page );
}

void SetHeaderVxDInfo(os2_flat_header *exe_head)
/**********************************************/
/* setup VxD specific info in the header */
{
    entry_export *exp;
    vxd_ddb      *ddb;

    exp = FmtData.u.os2.exports;
    if(( exp != NULL ) && ( exp->sym != NULL )) {
        ddb = (vxd_ddb*)((exp->sym->p.seg)->data);
        exe_head->r.vxd.device_ID = ddb->req_device_number;
        exe_head->r.vxd.DDK_version = ddb->SDK_version;
    }

}

extern void FiniOS2FlatLoadFile( void )
/*************************************/
/* make an OS/2 flat model executable file */
{
    os2_flat_header     exe_head;
    unsigned long       curr_loc;
    unsigned long       debug_size;
    unsigned_32         stub_len;
    unsigned long       count;
    unsigned            last_page;

    memset( &exe_head, 0, sizeof( exe_head ) ); /* zero all header fields */
    stub_len = Write_Stub_File();
    curr_loc  = sizeof(os2_flat_header);
    SeekLoad( stub_len + sizeof(os2_flat_header) );
    curr_loc += WriteObjectTables( &exe_head, curr_loc );
    exe_head.resname_off = curr_loc;
    curr_loc += ResNonResNameTable( TRUE );  // TRUE - do resident table.
    exe_head.rsrc_off = exe_head.resname_off;
    exe_head.num_rsrcs = 0;
    exe_head.entry_off = curr_loc;
    curr_loc += DumpFlatEntryTable();
    exe_head.loader_size = curr_loc - exe_head.objtab_off;
    exe_head.moddir_off = 0;
    curr_loc += WriteFixupTables( &exe_head, curr_loc );
    exe_head.impmod_off = curr_loc;
    curr_loc += ImportModTable( &count );
    exe_head.num_impmods = count;
    PadLoad( 1 );
    curr_loc += 1;
/* The minus one following is to allow for the fact that all OS/2 V2 import
 * by name offsets should be one less than the corresponding values in
 * V1.x -- yuck. */
    exe_head.impproc_off = curr_loc - 1;
    curr_loc += ImportProcTable( &count );
    exe_head.fixup_size = curr_loc - exe_head.fixpage_off;
    curr_loc = NullAlign( 4 );    /* align to dword boundary */
    exe_head.page_off = curr_loc;
    if( FmtData.type & MK_WIN_VXD ) {
        SetHeaderVxDInfo(&exe_head);
    }
    last_page = WriteDataPages( curr_loc );
    if( FmtData.type & (MK_OS2_LE|MK_WIN_VXD) ) {
        exe_head.l.last_page = last_page;
    } else {
        exe_head.l.page_shift = FmtData.u.os2.segment_shift;
    }
    exe_head.nonres_off = NullAlign( 1 ); /* cheap way of finding file pos */
    exe_head.nonres_size = ResNonResNameTable( FALSE );  // FALSE = do non-res.
    if( exe_head.nonres_size == 0 ) exe_head.nonres_off = 0;
    curr_loc = NullAlign( 1 );
    WriteDBI();
/* If debug info was written, we want to mark it in the header so that
 * RC doesn't throw it away! */
    SeekEndLoad(0);
    debug_size =  NullAlign( 1 )- curr_loc;
    if (debug_size) {
        exe_head.debug_off = curr_loc;
        exe_head.debug_len = debug_size;
    }
    if( FmtData.type & (MK_OS2_LE|MK_WIN_VXD) ) {
        exe_head.signature = OSF_FLAT_SIGNATURE;
    } else {
        exe_head.signature = OSF_FLAT_LX_SIGNATURE;
    }
    exe_head.byte_order = OSF_386_BYTE_ORDER;
    exe_head.word_order = OSF_386_WORD_ORDER;
    exe_head.level = OSF_EXE_LEVEL;
    if( FmtData.cpu_type <= 3 ) {
        exe_head.cpu_type = OSF_CPU_386;
    } else {
        exe_head.cpu_type = OSF_CPU_486;
    }
    if( FmtData.type & MK_WIN_VXD ) {
        exe_head.os_type = OSF_WIN386_LEVEL;
    } else {
        exe_head.os_type = OSF_OS_LEVEL;
    }
    if( FmtData.minor < 10 ) FmtData.minor *= 10;
    exe_head.version = FmtData.major * 100 + FmtData.minor;
    if( FmtData.type & MK_WIN_VXD ) { // VxD flags settings
        if( FmtData.u.os2.flags & VIRT_DEVICE ) {
            exe_head.flags |= VXD_DEVICE_DRIVER_DYNAMIC;
        } else if( FmtData.u.os2.flags & PHYS_DEVICE ) {
            exe_head.flags |= VXD_DEVICE_DRIVER_STATIC;
        } else {
            exe_head.flags |= VXD_DEVICE_DRIVER_3x;
        }
//        exe_head.heapsize  = FmtData.u.os2.heapsize;
    } else { // OS/2 flags settings
        if( FmtData.dll ) {
            exe_head.flags |= OSF_IS_DLL;
            // The OS/2 loader REALLY doesn't like to have these flags set if there
            // is no entrypoint!
            if (exe_head.start_obj != 0) {
                if( FmtData.u.os2.flags & INIT_INSTANCE_FLAG ) {
                    exe_head.flags |= OSF_INIT_INSTANCE;
                }
                if( FmtData.u.os2.flags & TERM_INSTANCE_FLAG ) {
                    exe_head.flags |= OSF_TERM_INSTANCE;
                }
            }
        } else if( FmtData.u.os2.flags & PHYS_DEVICE ) {
            exe_head.flags |= OSF_PHYS_DEVICE;
        } else if( FmtData.u.os2.flags & VIRT_DEVICE ) {
            exe_head.flags |= OSF_VIRT_DEVICE;
        } else {
            exe_head.stacksize = StackSize;
        }
        if( FmtData.u.os2.flags & PM_NOT_COMPATIBLE ) {
            exe_head.flags |= OSF_NOT_PM_COMPATIBLE;
        } else if( FmtData.u.os2.flags & PM_APPLICATION ) {
            exe_head.flags |= OSF_PM_APP;
        } else {
            exe_head.flags |= OSF_PM_COMPATIBLE;
        }
        if( LinkState & LINK_ERROR ) {
            exe_head.flags |= OSF_LINK_ERROR;
        }
        if( FmtData.type & MK_OS2_LX
            && (FmtData.u.os2.toggle_relocs ^ FmtData.u.os2.gen_int_relocs) ) {
            exe_head.flags |= OSF_INTERNAL_FIXUPS_DONE;
        }
        exe_head.heapsize  = FmtData.u.os2.heapsize;
    }
    exe_head.page_size = OSF_DEF_PAGE_SIZE;
    exe_head.num_preload = 0;   /* NYI: we should fill in this one correctly */
    exe_head.num_inst_preload = 0;  /*NYI: should fill in correctly */
    exe_head.num_inst_demand = 0;   /*NYI: should fill in correctly */
    SeekLoad( stub_len );
    WriteLoad( &exe_head, sizeof(os2_flat_header) );
}

extern bool FindOS2ExportSym( symbol *sym, dll_sym_info ** dllhandle )
/********************************************************************/
{
    dll_sym_info *      dll;

    if( sym->info & SYM_EXPORTED ) {
        dll = AllocDLLInfo();
        dll->isordinal = TRUE;
        dll->m.modnum = NULL;
        dll->u.ordinal = ((entry_export *)sym->e.export)->ordinal;
        *dllhandle = dll;
        return TRUE;
    }
    return FALSE;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?