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 + -
显示快捷键?